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

> OAuth 2.0のスコープとJWTクレームが、ユーザーに代わってアプリケーションがアクセスできるデータや実行できる操作をどのように制御するかを、実践的な例を通じて学びます。

# スコープとクレームのユースケース例

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

これらの例では、ユーザーを認証し、必要な権限 (スコープ) とトークンをリクエストするために、[Authorization Code Flow](/docs/ja-jp/get-started/authentication-and-authorization-flow/authorization-code-flow) を使用します。リクエストパラメーターの詳細や、このフローの完全な実装方法については、チュートリアル「[Add Login to Regular Web Applications](/docs/ja-jp/get-started/authentication-and-authorization-flow/authorization-code-flow/add-login-auth-code-flow)」をお読みください。

<div id="authenticate-a-user-and-request-standard-claims">
  ## ユーザーを認証して標準クレームをリクエストする
</div>

この例では、ユーザーを認証し、ユーザーインターフェースをパーソナライズするために必要なユーザー情報を取得します。そのためには、ユーザーの名前、ニックネーム、プロフィール画像、メール情報を含む<Tooltip tip="ID Token: リソースへのアクセスではなく、クライアント自身のための認証情報。" cta="用語集を見る" href="/docs/ja-jp/glossary?term=ID+token">ID トークン</Tooltip>を取得する必要があります。

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

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

   この例では、次の点に注目してください。

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

     * `code`: 通常の Web アプリフローを使用しているため、最初のリクエストでは認可コードを要求します。このコードを使ってトークンをリクエストすると、認証に必要な ID トークンを受け取れます。
   * `scope` パラメーターには、要求する OIDC スコープである 3 つの値が含まれます。

     * `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 をパーソナライズできます。

<div id="request-custom-api-access">
  ## カスタム API へのアクセスをリクエストする
</div>

この例では、呼び出し元のアプリケーションがユーザーの予定を読み取れるようにするため、カレンダー API 用のカスタム `scope` をリクエストします。これを行うには、API から予定を読み取るために必要な `scope` を含む <Tooltip tip="アクセストークン: API へのアクセスに使用される認可資格情報で、不透明な文字列または JWT の形式を取ります。" cta="用語集を見る" href="/docs/ja-jp/glossary?term=access+token">アクセストークン</Tooltip> を取得する必要があります。なお、アクセストークンのリクエストは、ID トークンのリクエストに依存しません。

カスタム API を使用する前に、呼び出す API で利用可能なスコープを把握しておく必要があります。カスタム API を自分で管理している場合は、アプリケーションと API の両方を Auth0 に登録し、[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" />

   この例では、次の点に注目してください。

   * `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 を呼び出します。

<div id="authenticate-a-user-and-request-standard-claims-and-custom-api-access">
  ## ユーザーを認証し、標準クレームとカスタム API へのアクセスをリクエストする
</div>

この例では、前の 2 つの例を組み合わせて、ユーザーを認証し、標準クレームをリクエストするとともに、カレンダー API 用のカスタム `scope` もリクエストします。これにより、呼び出し元のアプリケーションはそのユーザーの予定を読み取れるようになります。これを行うには、次の 2 つのトークンを取得します。

* 以下を含む ID トークン:

  * ユーザー名
  * ニックネーム
  * プロフィール画像
  * メール情報
* API から予定を読み取るための適切なスコープを含むアクセストークン。なお、アクセストークンのリクエストは ID トークンのリクエストに依存しません。

カスタム API を使用する前に、呼び出す API でどのようなスコープが利用できるかを把握しておく必要があります。カスタム API を自分で管理している場合は、アプリケーションと API の両方を Auth0 に登録し、[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" />

   この例では、次の点に注目してください。

   * `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 を呼び出します。

<div id="add-custom-claims-to-a-token">
  ## トークンにカスタムクレームを追加する
</div>

この例では、ユーザーのお気に入りの色と希望する連絡方法を ID トークン に追加します。これを行うには、[Action](/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 では名前空間付きクレームと名前空間なしクレームの両方を使用できますが、いくつかの制限があります ([一般的な制限](/docs/ja-jp/secure/tokens/json-web-tokens/create-custom-claims#general-restrictions) を参照) 。名前の衝突を避けるため、名前空間付きクレームを使用することをお勧めします。衝突が発生してもトランザクション自体は失敗しませんが、カスタムクレームはトークンに追加されません。
</Callout>

次のような状況を想定します。

* ユーザーは以前に、`preferred_contact` として `email` を、`favorite_color` として `red` を選択しており、それをユーザーの `user_metadata` の一部として保存しています。
* このユーザーに対して、[Management API](https://auth0.com/docs/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 tip="OpenID: ログイン情報を収集・保存することなく、アプリケーションがユーザーの本人確認を行えるようにする認証のためのオープン標準です。" cta="用語集を見る" href="/docs/ja-jp/glossary?term=OpenID">OpenID</Tooltip> Connect (OIDC) では、`favorite_color` や `user_metadata` を表す標準クレームが定義されていないためです。

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

1. [Auth0 Dashboard > Actions > Library](https://manage.auth0.com/#/actions/library) に移動し、**Build Custom** を選択します。

2. Action にわかりやすい **Name** (たとえば `Add user metadata to tokens`) を入力し、Login フローに Action を追加するため、トリガーとして `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) {
       // クレームを設定
       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. Action を本番環境で有効にする準備ができたら、**Deploy** を選択します。

最後に、作成した Action を [Login Flow](https://manage.auth0.com/#/actions/flows/login/) に追加します。Action を Flow に関連付ける方法については、[Write Your First Action](/docs/ja-jp/customize/actions/write-your-first-action) の "Attach the Action to a flow" セクションを参照してください。

この Action を有効にすると、Auth0 は `favorite_color` と `preferred_contac`t のカスタムクレームを 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,
  "https://myapp.example.com/favorite_color": "red",
  "https://myapp.example.com/preferred_contact": "email"
}
```

Action を作成する際は、追加のクレームをいつ含めるかを判断するロジックを設定してください。発行されるすべての ID トークンにカスタムクレームを追加するのは望ましくありません。

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

このトリガーのイベントオブジェクトについて詳しくは、[Actions Triggers: post-login - Event Object](/docs/ja-jp/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger/post-login-event-object) を参照してください。トークンについて詳しくは、[Tokens](/docs/ja-jp/secure/tokens) を参照してください。

<div id="learn-more">
  ## 詳細はこちら
</div>

* [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)
