> ## Documentation Index
> Fetch the complete documentation index at: https://docs-dev-fix-docs-5525.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# フォームPOSTを使った暗黙フローでログインを追加する

> フォームPOSTを使った暗黙フローでシングルページアプリケーション（SPA）へのログインを追加する方法を説明します。

export const AuthCodeBlock = ({filename, icon, language, highlight, children}) => {
  const [displayText, setDisplayText] = useState(children);
  const [copyText, setCopyText] = useState(children);
  const wrapperRef = React.useRef(null);
  useEffect(() => {
    let unsubscribe = null;
    function init() {
      if (!window.autorun || !window.rootStore) {
        return;
      }
      unsubscribe = window.autorun(() => {
        let processedChildrenForDisplay = children;
        let processedChildrenForCopy = children;
        for (const [key, value] of window.rootStore.variableStore.values.entries()) {
          const escapedKey = key.replaceAll(/[.*+?^${}()|[\]\\]/g, (String.raw)`\$&`);
          let displayValue = value;
          if (key === "{yourClientSecret}" && value !== "{yourClientSecret}") {
            displayValue = value.substring(0, 3) + "*****MASKED*****";
          }
          processedChildrenForDisplay = processedChildrenForDisplay.replaceAll(new RegExp(escapedKey, "g"), displayValue);
          processedChildrenForCopy = processedChildrenForCopy.replaceAll(new RegExp(escapedKey, "g"), value);
        }
        setDisplayText(processedChildrenForDisplay);
        setCopyText(processedChildrenForCopy);
      });
    }
    if (window.rootStore) {
      init();
    } else {
      window.addEventListener("adu:storeReady", init);
    }
    return () => {
      window.removeEventListener("adu:storeReady", init);
      unsubscribe?.();
    };
  }, [children]);
  useEffect(() => {
    if (!wrapperRef.current) return;
    const originalWriteText = navigator.clipboard.writeText.bind(navigator.clipboard);
    let isOverriding = false;
    const handleClick = e => {
      const button = e.target.closest('[data-testid="copy-code-button"]');
      if (!button || !wrapperRef.current.contains(button)) return;
      isOverriding = true;
      navigator.clipboard.writeText = text => {
        if (isOverriding) {
          isOverriding = false;
          navigator.clipboard.writeText = originalWriteText;
          return originalWriteText(copyText);
        }
        return originalWriteText(text);
      };
      setTimeout(() => {
        if (isOverriding) {
          isOverriding = false;
          navigator.clipboard.writeText = originalWriteText;
        }
      }, 100);
    };
    const wrapper = wrapperRef.current;
    wrapper.addEventListener('click', handleClick, true);
    return () => {
      wrapper.removeEventListener('click', handleClick, true);
      if (navigator.clipboard.writeText !== originalWriteText) {
        navigator.clipboard.writeText = originalWriteText;
      }
    };
  }, [copyText]);
  return <div ref={wrapperRef}>
      <CodeBlock filename={filename} icon={icon} language={language} lines highlight={highlight}>
        {displayText}
      </CodeBlock>
    </div>;
};

フォームPOSTを使った暗黙フローでシングルページアプリケーション（SPA）へのログインを追加することができます。フローの仕組みやメリットについては、「[フォームPOSTを使った暗黙フロー](/docs/ja-jp/get-started/authentication-and-authorization-flow/implicit-flow-with-form-post)」をお読みください。

フォームPOSTを使った暗黙フローは、ログインのみのユースケースに使用します。ユーザーのログイン時にAPIを呼び出せるようにアクセストークンを要求する場合は、PKCEを使った認可コードフローを使用してください。詳細については、「[Proof Key for Code Exchange（PKCE）を使った認可コードフロー](/docs/ja-jp/get-started/authentication-and-authorization-flow/authorization-code-flow-with-pkce)」をお読みください。

フォームPOSTを使った暗黙フローを実装するには、以下のリソースを使用することができます。

* [Express OpenID Connect SDK](https://www.npmjs.com/package/express-openid-connect)：フローを実装する最も簡単な方法です。難しくて手間がかかる作業のほとんどが処理されます。Javascript SDKを使用する場合は、アーキテクチャに適した軽減措置を実施しているか確認してください。詳細については、「[Auth0.js v9の参考情報](/docs/ja-jp/libraries/auth0js)」をお読みください。
* [Authentication API](/docs/ja-jp/api/authentication)：独自のソリューションを構築したい場合は、このまま読み続けて、APIを直接呼び出す方法を学習してください。

ログインに成功すると、アプリケーションがユーザーの[IDトークン](/docs/ja-jp/secure/tokens/id-tokens)にアクセスします。IDトークンには基本的なプロファイル情報が含まれます。

## 前提条件

アプリをAuth0に登録する必要があります。詳細については、「[シングルページアプリケーションの登録](/docs/ja-jp/get-started/auth0-overview/create-applications/single-page-web-apps)」をお読みください。

* **［Single-Page App（シングルページアプリ）］** を **［Application Type（アプリケーションタイプ）］** として選択します。
* `{https://yourApp/callback}`の **［Allowed Callback URL（許可されているコールバックURL）］** を追加します。
* アプリケーションの **［Grant Types（付与タイプ）］** に **［Implicit（暗黙）］** が含まれていることを確認します。詳細については、「[付与タイプを更新する](/docs/ja-jp/get-started/applications/update-grant-types)」をお読みください。

## ユーザーを認可する

ユーザーの認可を要求しすると、アプリにリダイレクトされます。フローを開始するには、ユーザーの認可が必要です。この手順には、以下のようなプロセスが含まれます。

* ユーザーを認証する
* 認証を行うために、ユーザーをIDプロバイダーへリダイレクトする
* 有効なシングルサインオン（<Tooltip data-tooltip-id="react-containers-DefinitionTooltip-0" href="/docs/ja-jp/glossary?term=single-sign-on" tip="シングルサインオン（SSO）: ユーザーが1つのアプリケーションにログインした後、そのユーザーを他のアプリケーションに自動的にログインさせるサービス。" cta="用語集の表示">SSO</Tooltip>）セッションを確認する
* 以前に同意を得ていない場合は、要求された権限レベルについてユーザーの同意を得る

ユーザーを認可するには、アプリがユーザーに認可URLを送信する必要があります。

### 認可URLの例

export const codeExample1 = `https://{yourDomain}/authorize?
    response_type=YOUR_RESPONSE_TYPE&
    response_mode=form_post&
    client_id={yourClientId}&
    redirect_uri={https://yourApp/callback}&
    scope=SCOPE&
    state=STATE&
    nonce=NONCE`;

<AuthCodeBlock children={codeExample1} language="text" lines />

### パラメーター

| パラメーター名         | 説明                                                                                                                                                                                                                                                                                                                                                                                                        |
| --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `response_type` | Auth0が返す資格情報の種類を示します（コードまたはトークン）。暗黙フローに対して、値は`id_token`、`token`、`id_token token`になります。特に、`id_token`はIDトークンを返し、`token`はアクセストークンを返します。                                                                                                                                                                                                                                                                      |
| `response_mode` | 応答パラメーターが返される方法を指定します。安全保護のため、値は`form_post`にする必要があります。このモードでは、応答パラメーターは、HTTP POSTメソッドを介して送信され、`application/x-www-form-urlencoded`フォーマットを使用して本文でエンコードされるHTMLフォーム値としてエンコードされます。                                                                                                                                                                                                                             |
| `client_id`     | アプリケーションのクライアントID。これは、[アプリケーション設定](https://manage.auth0.com/#/applications/\{yourClientId}/settings)で見つけることができます。                                                                                                                                                                                                                                                                                         |
| `redirect_uri`  | 認可がユーザーにより付与された後にAuth0がブラウザをリダイレクトするURL。[Application Settings（アプリケーション設定）](https://manage.auth0.com/#/Applications/\{yourClientId}/settings)で有効なCallback URLとしてこのURLを指定する必要があります。<br /><br />**警告：** [OAuth 2.0の仕様](https://tools.ietf.org/html/rfc6749#section-3.1.2)に従って、Auth0はハッシュの後、すべてを削除し、フラグメントを尊重*しません*。                                                                                          |
| `scope`         | 返したいクレーム（またはユーザー属性）を決定する、認可を要求したい[スコープ](/docs/ja-jp/scopes)を指定します。スペースで区切る必要があります。`profile`および`email`などのユーザーに関する[標準OpenID Connect（OIDC）スコープ](https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims)、[名前空間形式](/docs/ja-jp/tokens/guides/create-namespaced-custom-claims)に従った[カスタムクレーム](/docs/ja-jp/tokens/concepts/jwt-claims#custom-claims)、ターゲットAPIがサポートするスコープ（例：`read:contacts`）を要求できます。 |
| `state`         | （推奨）Auth0がリダイレクトしてアプリケーションに戻る際に含まれ、アプリが初期要求に追加する不透明な任意の英数字の文字列。クロスサイトリクエストフォージェリ（CSRF）攻撃を防止するためにこの値を使用する方法については、[状態パラメーターを使ってCSRF攻撃を軽減する](/docs/ja-jp/protocols/oauth2/mitigate-csrf-attacks)をご覧ください。                                                                                                                                                                                                     |
| `nonce`         | （`id_token token`を含む`response_type`に必要、そうでない場合は推奨）[トークンリプレイ攻撃を防ぐために使用される](/docs/ja-jp/api-auth/tutorials/nonce)、アプリが初期要求に追加し、Auth0がIDトークンに含める暗号的にランダムな文字列。                                                                                                                                                                                                                                                |
| `connection`    | （任意）特定の接続でユーザーにサインインを強制します。たとえば、`github`の値を渡して、GitHubアカウントでログインするようにユーザーを直接GitHubに送信します。指定しなかった場合、ユーザーには、構成された接続すべてが表示されたAuth0 Lock画面が表示されます。アプリケーションの**Connections（接続）** タブで構成された接続のリストを確認できます。                                                                                                                                                                                                          |
| `organization`  | （任意）ユーザーを認証する時に使用する組織のID。提供されない場合、アプリケーションは**Display Organization Prompt（組織のプロンプトを表示）** に設定され、ユーザーは、認証時に組織名を入力できます。                                                                                                                                                                                                                                                                                       |
| `invitation`    | （任意）組織の招待のチケットID。[Organizationにメンバーを招待する](/docs/ja-jp/organizations/invite-members)場合、ユーザーが招待を受け入れたとき、アプリケーションは、`invitation`および`organization`のキー/値ペアを転送することで、招待の受け入れを処理する必要があります。                                                                                                                                                                                                                         |

たとえば、アプリにログインを追加する際の認可URLのHTMLスニペットは、以下のようになります。

export const codeExample2 = `<a href="https://{yourDomain}/authorize?
  response_type=id_token token&
  response_mode=form_post&
  client_id={yourClientId}&
  redirect_uri={https://yourApp/callback}&
  scope=read:tests&
  state=xyzABC123&
  nonce=eq...hPmz">
  Sign In
</a>`;

<AuthCodeBlock children={codeExample2} language="html" />

### 応答

すべてが成功すると`、HTTP 302`応答を受け取ります。要求された資格情報は本文にエンコードされます。

```lines theme={null}
HTTP/1.1 302 Found
Content-Type: application/x-www-form-urlencoded
id_token=eyJ...acA&
state=xyzABC123
```

返される値は、`response_type`として何を要求したかによって異なります。

| 応答タイプ           | コンポーネント                                         |
| --------------- | ----------------------------------------------- |
| id\_token       | IDトークン                                          |
| token           | アクセストークン（および`expires_in`と`token_type`の値）        |
| id\_token token | IDトークン、アクセストークン（および`expires_in`と`token_type`の値） |

Auth0は、認可URLへの呼び出しに含めた状態値も返します。

<Warning>
  トークンは、検証してから保存します。操作方法については、「[IDトークンの検証](/docs/ja-jp/secure/tokens/id-tokens/validate-id-tokens)」および「[アクセストークンを検証する](/docs/ja-jp/secure/tokens/access-tokens/validate-access-tokens)」を参照してください。
</Warning>

IDトークンには、デコードして抽出する必要があるユーザー情報が含まれています。

## ユースケース

### 基本的な認証要求

この例では、手順1でユーザーを認可する際に行う最も基本的な要求について説明します。Auth0のログイン画面を表示して、構成されている接続でユーザーがサインインできるようにします。

export const codeExample3 = `https://{yourDomain}/authorize?
    response_type=id_token&
    response_mode=form_post&
    client_id={yourClientId}&
    redirect_uri={https://yourApp/callback}&
    nonce=NONCE`;

<AuthCodeBlock children={codeExample3} language="text" lines />

これによってIDトークンが返され、リダイレクトURLから解析することができます。

### ユーザーの名前とプロファイルの写真を要求する

通常のユーザー認証に加えて、この例では名前や写真など、追加のユーザー詳細情報を要求する方法について説明します。

ユーザーの名前や写真を要求するには、ユーザーを認可する際に、適切なスコープを追加する必要があります。

export const codeExample4 = `https://{yourDomain}/authorize?
    response_type=id_token token&
    response_mode=form_post&
    client_id={yourClientId}&
    redirect_uri={https://yourApp/callback}&
    scope=openid%20name%20picture&
    state=STATE&
    nonce=NONCE`;

<AuthCodeBlock children={codeExample4} language="text" lines />

これで、IDトークンには要求された名前と写真のクレームが含まれます。IDトークンをデコードする際には、以下のようになります。

```json lines theme={null}
{
  "name": "jerrie@...",
  "picture": "https://s.gravatar.com/avatar/6222081fd7dcea7dfb193788d138c457?s=480&r=pg&d=https%3A%2F%2Fcdn.auth0.com%2Favatars%2Fje.png",
  "iss": "https://auth0pnp.auth0.com/",
  "sub": "auth0|581...",
  "aud": "xvt...",
  "exp": 1478113129,
  "iat": 1478077129
}
```

### GitHubでのユーザーログインを要求する

通常のユーザー認証に加えて、この例では、ユーザーをGitHubなどのソーシャルIDプロバイダーへ直接送る方法について説明します。この例を利用するには、[［Auth0 Dashboard］>［Authentication（認証）］>［Social（ソーシャル）］](https://manage.auth0.com/#/connections/social)の順に移動し、適切な接続を構成します。**［Settings（設定）］** タブから接続名を取得します。

ユーザーをGitHubログイン画面に直接送るには、ユーザーを認可する際に`connection`パラメーターを渡し、その値を接続名（この場合、`github`）に設定する必要があります。

export const codeExample5 = `https://{yourDomain}/authorize?
    response_type=id_token token&
    response_mode=form_post&
    client_id={yourClientId}&
    redirect_uri={https://yourApp/callback}&
    scope=openid%20name%20picture&
    state=STATE&
    nonce=NONCE&
    connection=github`;

<AuthCodeBlock children={codeExample5} language="text" lines />

これで、`sub`クレームがGitHubから返されたユーザーの一意のIDとともにIDトークンに表示されます。IDトークンをデコードする際には、以下のようになります。

```json lines theme={null}
{
  "name": "Jerrie Pelser",
  "nickname": "jerriep",
  "picture": "https://avatars.githubusercontent.com/u/1006420?v=3",
  "iss": "https://auth0pnp.auth0.com/",
  "sub": "github|100...",
  "aud": "xvt...",
  "exp": 1478114742,
  "iat": 1478078742
}
```

## もっと詳しく

* [OAuth 2.0の認可フレームワーク](/docs/ja-jp/authenticate/protocols/oauth)
* [OpenID Connectのプロトコル](/docs/ja-jp/authenticate/protocols/openid-connect-protocol)
* [トークン](/docs/ja-jp/secure/tokens)
* [暗黙フロー使用時にリプレイ攻撃を軽減する](/docs/ja-jp/get-started/authentication-and-authorization-flow/implicit-flow-with-form-post/mitigate-replay-attacks-when-using-the-implicit-flow)
* [シングルページWebアプリケーションを登録する](/docs/ja-jp/get-started/auth0-overview/create-applications/single-page-web-apps)
* [付与タイプの更新](/docs/ja-jp/get-started/applications/update-grant-types)
