> ## 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.

> アプリケーションと 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) + "*****マスク済み*****";
          }
          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](/ja/docs/get-started/authentication-and-authorization-flow/authorization-code-flow) を使用してユーザーを認証し、必要な権限 (スコープ) とトークンをリクエストします。リクエストパラメーターの詳細や、このフローを完全に実装する方法については、チュートリアル「[Add Login to Regular Web Applications](/ja/docs/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="/ja/docs/glossary?term=ID+token">IDトークン</Tooltip>を取得する必要があります。

1. ユーザーを認可 URL にリダイレクトして、認証フローを開始します。

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

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

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

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

     * `openid`: アプリケーションが OIDC を使用してユーザーの本人確認を行うことを示します。
     * `profile`: `name`、`nickname`、`picture` を取得します。
     * `email`: `email` と `email_verified` を取得します。
2. ユーザーが同意した後 (必要な場合) 、Auth0 がアプリにリダイレクトしたら、[トークンをリクエストします](/ja/docs/get-started/authentication-and-authorization-flow/authorization-code-flow/add-login-auth-code-flow)。
3. レスポンスから IDトークンを抽出し、[デコードします](/ja/docs/secure/tokens/id-tokens)。次のクレームが表示されるはずです。

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

   これでアプリでユーザー属性を取得し、それらを使って UI をパーソナライズできます。

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

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

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

1. ユーザーを認可 URL にリダイレクトして、認可フローを開始します。

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

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

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

     * `code`: 通常の Web アプリのフローを使用しているため、最初のリクエストでは認可コードを要求します。この code を使ってトークンを要求すると、API の呼び出しに使用できるアクセストークンを受け取ります。
   * `scope` パラメーターには 1 つの値、つまり要求する API のスコープが含まれます。

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

     * ユーザーの予定を読み取りたい API の一意の識別子です。
2. 前の例と同様に、ユーザーが同意すると (必要な場合) 、Auth0 はアプリにリダイレクトします。その後、[トークンを要求します](/ja/docs/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 用のカスタムスコープも要求します。これを行うには、2 つのトークンを取得します。

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

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

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

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

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

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

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

     * `code`: 通常の Web アプリケーションフローを使用しているため、最初のリクエストでは認可コードを要求します。この `code` を使用してトークンを要求すると、認証に必要な 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](/ja/docs/customize/actions) を作成し、これらの [クレーム](/ja/docs/secure/tokens/json-web-tokens/create-custom-claims) を追加して IDトークン をカスタマイズします。追加後は、`/userinfo` エンドポイントの呼び出し時にもカスタムクレームを取得できるようになります (ただし、Action が実行されるのは認証プロセス中のみです) 。

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  Auth0 では名前空間付きクレームと名前空間なしクレームの両方を使用できますが、一定の制限があります ([一般的な制限事項](/ja/docs/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 に保存される[正規化ユーザープロファイル](/ja/docs/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` プロパティの値が含まれます。
* <Tooltip tip="OpenID: ログイン情報を収集・保存することなく、アプリケーションがユーザーの本人確認を行えるようにする認証のためのオープン標準。" cta="用語集を表示" href="/ja/docs/glossary?term=OpenID">OpenID</Tooltip> Connect (OIDC) では、`favorite_color` または `user_metadata` を表す標準クレームが定義されていないため、`favorite_color` プロパティも `user_metadata` プロパティも含まれていません。

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

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

2. Action のわかりやすい **名前** を入力し (例: `Add user metadata to tokens`) 、この Action を Login フローに追加するため、`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** を選択して[コードをテスト](/ja/docs/customize/actions/test-actions)します。

5. Action を公開する準備ができたら、**Deploy** を選択します。

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

この Action を有効にすると、Auth0 は `favorite_color` と `preferred_contact` のカスタムクレームを 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` メソッドを使用します。

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

<div id="learn-more">
  ## 詳細
</div>

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