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

# 「サンプルユースケース」の「スコープとクレーム」

> アプリケーションとAPIを用いたスコープとクレームの使用方法を説明します。

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>;
};

export const codeExample1 = `https://{yourDomain}/authorize?
  response_type=code&
  client_id={yourClientId}&
  redirect_uri={https://yourApp/callback}&
  scope=openid%20profile%20email&
  state=YOUR_STATE_VALUE
`;

export const codeExample2 = `{
  "name": "John Doe",
  "nickname": "john.doe",
  "picture": "https://myawesomeavatar.com/avatar.png",
  "updated_at": "2017-03-30T15:13:40.474Z",
  "email": "john.doe@test.com",
  "email_verified": false,
  "iss": "https://{yourDomain}/",
  "sub": "auth0|USER-ID",
  "aud": "{yourClientId}",
  "exp": 1490922820,
  "iat": 1490886820,
  "nonce": "crypto-value",
  "at_hash": "IoS3ZGppJKUn3Bta_LgE2A"
}`;

export const codeExample3 = `https://{yourDomain}/authorize?
  response_type=code&
  client_id={yourClientId}&
  redirect_uri={https://yourApp/callback}& 
  scope=read:appointments&
  audience=YOUR_API_AUDIENCE&
  state=YOUR_STATE_VALUE
`;

export const codeExample4 = `https://{yourDomain}/authorize?
  response_type=code&
  client_id={yourClientId}&
  redirect_uri={https://yourApp/callback}& 
  scope=openid%20profile%20email%20read:appointments&
  audience=YOUR_API_AUDIENCE&
  state=YOUR_STATE_VALUE
`;

以下の例では、[認可コードフロー](/docs/ja-jp/get-started/authentication-and-authorization-flow/authorization-code-flow)を使ってユーザーを認証し、必要な権限（スコープ）とトークンを要求します。要求パラメーターおよびこのフローの完全実装の詳細については、チュートリアル「[ログインを通常のWebアプリケーションに追加する](/docs/ja-jp/get-started/authentication-and-authorization-flow/authorization-code-flow/add-login-auth-code-flow)」をお読みください。

## ユーザーを認可して標準クレームを要求する

この例では、ユーザーを認証し、ユーザーインターフェイスをパーソナライズできるようにユーザー詳細を取得したいとします。このためには、ユーザー名、ニックネーム、プロフィール画像、およびメール情報を含んだIDトークンが必要です。

1. ユーザーに認証URLを送信して、認可フローを開始します。

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

   この例では、以下の点に注意してください。

   * `response_type`パラメーターには1つの値が含まれます。

     * `code`：標準のWebアプリケーションを使用しているため、最初に認証コードに対する要求が行われます。このコードを使ってトークンを要求すると、認証に必要なIDトークンが送られてきます。
   * `scope`パラメーターには、3つの値（要求されたOIDCスコープ）が含まれます。

     * `openid`：アプリケーションがユーザーの身元検証にOIDCを使用することを伝えるため
     * `profile`：`name`、`nickname`、および`picture`を取得するため
     * `email`：`email`と`email_verified`を取得するため
2. ユーザーが同意し（必要な場合）、Auth0がアプリにリダイレクトした後、[トークンを要求します](/docs/ja-jp/get-started/authentication-and-authorization-flow/authorization-code-flow/add-login-auth-code-flow)。
3. 応答からIDトークンを抽出し、[解読します](/docs/ja-jp/secure/tokens/id-tokens)。次のクレームが表示されます。

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

   アプリはユーザー属性を取得し、この属性を使ってUIをパーソナライズできるようになります。

## カスタムAPIへのアクセスを要求する

以下の例では、呼び出す側のアプリケーションがユーザーの予定を読み取れるようにするカレンダーAPIのカスタムスコープを要求します。このため、APIから予定を読み取るための適切なスコープを含んだアクセストークンを取得します。アクセストークンの要求は、IDトークンの要求に依存することはありません。

カスタムAPIを使用する前に、呼び出すAPIで使用できるスコープを知っておく必要があります。カスタムAPIを管理できる場合、Auth0を使ってアプリケーションとAPIの両方を登録し、[Auth0 DashboardでAPIのスコープを定義する](/docs/ja-jp/get-started/apis/scopes/api-scopes)必要があります。定義された権限を使って、ユーザーの[同意プロンプトをカスタマイズする](/docs/ja-jp/customize/login-pages/customize-consent-prompts)こともできます。

1. ユーザーに認証URLを送信して、認可フローを開始します。

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

   この例では、以下の点に注意してください。

   * `response_type`パラメーターには1つの値が含まれたままです。

     * `code`：標準のWebアプリケーションを使用しているため、最初に認証コードに対する要求が行われます。このコードを使ってトークンを要求すると、APIの呼び出しに使用できるアクセストークンが送られてきます。
   * `scope`パラメーターには、1つの値（要求されたAPIスコープ）が含まれます。

     * `read:appointments`：APIからユーザーの予定を読み取れるようにするため
   * `audience`パラメーターは新しいパラメーターで、1つの値が含まれます。

     * APIの一意識別子で、ここからユーザーの予定を読み取ります。
2. 前の例にあるように、ユーザーが同意し（必要な場合）、Auth0がアプリにリダイレクトした後、[トークンを要求します](/docs/ja-jp/get-started/authentication-and-authorization-flow/authorization-code-flow/add-login-auth-code-flow)。
3. 応答からアクセストークンを抽出し、アクセストークンを資格情報に使ってAPIを呼び出します。

## ユーザーを認可し、標準クレームとカスタムAPIアクセスを要求します。

この例では、前の2つの例を組み合わせて、ユーザーの認可と標準クレームの要求を行うほか、呼び出す側のアプリケーションがユーザーの予定を読み取れるようにするカレンダーAPIのカスタムスコープも要求します。このために、2つのトークンを取得します。

* IDトークンに含まれるもの：

  * ユーザー名
  * Nickname（ニックネーム）
  * プロファイル画像
  * メール情報
* 適切なスコープを含むトークンにアクセスし、APIから予定を読み取ります。アクセストークンの要求は、IDトークンの要求に依存することはありません。

カスタムAPIを使用する前に、呼び出すAPIで使用できるスコープを知っておく必要があります。カスタムAPIを管理できる場合、Auth0を使ってアプリケーションとAPIの両方を登録し、[Auth0 DashboardでAPIのスコープを定義する](/docs/ja-jp/get-started/apis/scopes/api-scopes)必要があります。定義された権限を使って、ユーザーの[同意プロンプトをカスタマイズする](/docs/ja-jp/customize/login-pages/customize-consent-prompts)こともできます。

1. ユーザーに認証URLを送信して、認可フローを開始します。

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

   この例では、以下の点に注意してください。

   * `response_type`パラメーターには1つの値が含まれたままです。

     * `code`：標準のWebアプリケーションを使用しているため、最初に認証コードに対する要求が行われます。このコードを使ってトークンを要求すると、認証に必要なIDトークンとAPIの呼び出しに使用できるアクセストークンの両方が送られてきます。
   * `scope`パラメーターはOIDCスコープとAPIスコープの両方に使用されるため、4つの値が含まれるようになりました。

     * `openid`：アプリケーションがユーザーの身元検証にOIDCを使用することを伝えるため
     * `profile`：`name`、`nickname`、および`picture`を取得するため
     * `email`：`email`と`email_verified`を取得するため
     * `read:appointments`：APIからユーザーの予定を読み取れるようにするため
   * `audience`パラメーターには1つの値が含まれます。

     * APIの一意識別子で、ここからユーザーの予定を読み取ります。
2. 前の例にあるように、ユーザーが同意し（必要な場合）、Auth0がアプリにリダイレクトした後、トークンを要求します。
3. 応答からIDトークンを抽出、解読し、ユーザー属性を取得し、その属性を使ってUIをパーソナライズします。
4. 応答からアクセストークンを抽出し、アクセストークンを資格情報に使ってAPIを呼び出します。

## カスタムクレームをトークンに追加する

以下の例では、ユーザーのお気に入りの色と使用する連絡先方法をIDトークンに追加します。このためには、これらの[クレーム](/docs/ja-jp/customize/actions)を追加することで、[アクション](/docs/ja-jp/secure/tokens/json-web-tokens/create-custom-claims)を作成し、IDトークンをカスタマイズします。追加すると、`/userinfo`エンドポイントを呼び出すときに、カスタムクレームを取得することもできます（ただし、Actionは認可プロセス中のみ実行されます）。

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  Auth0では、名前空間を指定したクレームと名前空間を指定しないクレームが使用できますが、特定の制限があります（「[一般的な制限](https://auth0.com/docs/secure/tokens/json-web-tokens/create-custom-claims#general-restrictions)」を参照してください）。名前の衝突を避けるために、名前空間を指定したクレームの使用をお勧めします。衝突が生じた場合、トランザクションは失敗しませんが、カスタムクレームがトークンに追加されません。
</Callout>

以下のように仮定します。

* ユーザーが`preferred_contact`メソッドに`email`、`favorite_color`に`red`をぞれぞれ選択し、ユーザーの`user_metadata`の一部として保存しました。
* [Management API](/docs/ja-jp/api/management/v2#!/Users/patch_users_by_id)またはDashboardを使用して、このユーザーのアプリケーション固有情報を設定しました。

この場合、Auth0に保存されている[正規化ユーザープロファイル](/docs/ja-jp/manage-users/user-accounts/user-profiles/normalized-user-profiles)は以下のとおりです。

```json lines theme={null}
{
  "email": "jane@example.com",
  "email_verified": true,
  "user_id": "custom|123",
  "favorite_color": "blue",
  "user_metadata": {
    "preferred_contact": "email"
  }
}
```

このプロファイルでは、Auth0は通常、以下のIDトークンのクレームをアプリケーションに返します。

```json lines theme={null}
{
  "email": "jane@example.com",
  "email_verified": true,
  "iss": "https://my-domain.auth0.com/",
  "sub": "custom|123",
  "aud": "my_client_id",
  "iat": 1311280970,
  "exp": 1311281970
}
```

この例では、以下の点に注意してください。

* `sub`クレームには、`user_id`プロパティの値が含まれます。
* `favorite_color`プロパティも`user_metadata`プロパティも存在しません。これは、<Tooltip data-tooltip-id="react-containers-DefinitionTooltip-0" href="/docs/ja-jp/glossary?term=openid" tip="OpenID: アプリケーションがログイン情報を収集および保存することなくにユーザーのIDを検証できるようにする認証用のオープン標準。" cta="用語集の表示">OpenID</Tooltip> Connect (OIDC)が`favorite_color`または`user_metadata`を表す標準クレームを定義しないためです。

カスタムデータを受け取るには、[新しいアクションを作成し](/docs/ja-jp/customize/actions/write-your-first-action)、ユーザープロファイルからのプロパティを表す[カスタムクレーム](/docs/ja-jp/secure/tokens/json-web-tokens/create-custom-claims)を使ってトークンをカスタマイズする必要があります。

1. [［Auth0 Dashboard］>［Actions（アクション）］>［Library（ライブラリ）］](https://manage.auth0.com/#/actions/library)に移動し、**［Build Custom（カスタムビルド）］** を選択します。

2. アクションにわかりやすい **名前** を入力し（たとえば、「`ユーザーメタデータをトークンに追加する`」）、`［Login / Post Login（ログイン/ログイン後）］`トリガーを選択し（アクションをログインフローに追加することになるため）、 **［Create（作成）］** を選択します。

3. Actions Code Editor（アクションコードエディター）を検索し、以下のJavaScriptコードをコピーし、 **［Save Draft（下書きを保存）］** を選択して内容を保存します。

   ```javascript lines theme={null}
   exports.onExecutePostLogin = async (event, api) => {
     const namespace = 'https://myapp.example.com';
     const { favorite_color, preferred_contact } = event.user.user_metadata;

     if (event.authorization) {
       // Set claims 
       api.idToken.setCustomClaim(`${namespace}/favorite_color`, favorite_color);
       api.idToken.setCustomClaim(`${namespace}/preferred_contact`, preferred_contact);
     }
   };
   ```

4. ［Actions Code Editor（アクションコードエディター）］サイドバーから、［Test（テスト）］（再生アイコン）、 **［Run（実行）］** の順にクリックし、[コードをテストします](/docs/ja-jp/customize/actions/test-actions)。

5. アクションを稼働する準備ができたら、 **［Deploy（導入）］** を選択します。

そして、作成したアクションを[［Login Flow（ログインフロー）］](https://manage.auth0.com/#/actions/flows/login/)に追加します。アクションをフローにアタッチする方法については、[初めてアクションを作成する](/docs/ja-jp/customize/actions/write-your-first-action)の「アクションをフローにアタッチする」セクションをお読みください。

このアクションが有効な場合、Auth0では、IDトークンに`favorite_color`および`preferred_contact`のカスタムクレームが含まれます。

```json lines theme={null}
{
  "email": "jane@example.com",
  "email_verified": true,
  "iss": "https://my-domain.auth0.com/",
  "sub": "custom|123",
  "aud": "my_client_id",
  "iat": 1311280970,
  "exp": 1311281970,
  "https://myapp.example.com/favorite_color": "red",
  "https://myapp.example.com/preferred_contact": "email"
}
```

アクションを作成する場合、追加のクレームを含めるタイミングを決める何らかのロジックを必ず設定してください。カスタムクレームを発行されている各IDトークンに注入することは推奨しません。

この例では、カスタムクレームが`api.idToken.setCustomClaims`メソッドを使用するIDトークンに追加されています。これらのクレームをアクセストークンに追加するには、`api.accessToken.setCustomClaim`メソッドを使用します。

トリガーのイベントオブジェクトの詳細については、「[Actionトリガー：post-login - eventオブジェクト](/docs/ja-jp/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger/post-login-event-object)」をお読みください。トークンの詳細については、「[トークン](/docs/ja-jp/secure/tokens)」をお読みください。

## もっと詳しく

* [OpenID Connectのスコープ](/docs/ja-jp/get-started/apis/scopes/openid-connect-scopes)
* [カスタムクレームを作成する](/docs/ja-jp/secure/tokens/json-web-tokens/create-custom-claims)
* [APIスコープ](/docs/ja-jp/get-started/apis/scopes/api-scopes)
* [複数のAPIの論理APIを構成する](/docs/ja-jp/get-started/apis/set-logical-api)
