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

> アプリケーションが Token Vault にアクセスして Auth0 のアクセストークンを外部 API 呼び出し用のアクセストークンに交換する方法を学びます。

# Token Vault を使用したアクセストークンの交換

Token Vault はアクセストークンの交換をサポートしており、これによりクライアントアプリケーションは Auth0 のアクセストークン（subject token）を外部プロバイダーのアクセストークン（requested token）と交換できます。

シングルページアプリケーション (SPA) がバックエンド API を呼び出すとき、`Authorization` ヘッダーには Auth0 のアクセストークンのみが渡されます。バックエンド API は SPA に発行されたリフレッシュトークンを受け取らないため、[refresh token exchange](/docs/ja-JP/secure/tokens/token-vault/refresh-token-exchange-with-token-vault) を利用して Token Vault にアクセスし、外部 API を呼び出すことはできません。

その代わりに、バックエンド API は SPA から受け取った Auth0 のアクセストークンを外部プロバイダーのアクセストークンと交換できます。これをアクセストークンの交換と呼びます。このプロセスにより、機密性の高い外部クレデンシャルはバックエンド側で安全に保護されます。

Auth0 のアクセストークン交換では、バックエンド API はクライアントとリソースサーバーの両方として動作します。

* クライアント: 自身のクレデンシャルを使用して、Auth0 認可サーバーと安全にアクセストークンの交換を行います。Auth0 では、バックエンド API と同じ識別子を持つ Custom API Client を作成します。バックエンド API は、この Custom API Client のクレデンシャルを渡して、Auth0 認可サーバーと安全にアクセストークンの交換を行います。
* リソースサーバー: SPA に対してバックエンド API を提供し、Auth0 のアクセストークンを検証します。

SPA と Auth0 認可サーバーの間の仲介役として動作することで、バックエンド API は、不正なクライアントが Auth0 のトークンを盗み、ユーザーに代わって外部プロバイダーへアクセスすることを防止します。

<div id="use-cases">
  ## ユースケース
</div>

アクセストークンの交換が利用される一般的なユースケースには、次のようなものがあります。

* バックエンド API: ユーザーが SPA とやり取りし、その SPA が Auth0 認可サーバーを使って Auth0 のアクセストークンを外部プロバイダーのアクセストークンに交換するためにバックエンド API を呼び出すケース。
* マイクロサービスアーキテクチャ: MCP サーバーやその他の OAuth 2.0 リソースサーバーなど、外部 API にアクセスするためにアクセストークンを交換する必要があるバックエンドサービスのケース。

<div id="how-it-works">
  ## 仕組み
</div>

次のシーケンス図は、Auth0 のアクセストークンエクスチェンジを使用して外部 API を呼び出すまでのエンドツーエンドの流れを示しています。

<Frame>
  <img src="https://mintcdn.com/generaltranslationinc/78hG6sVmUVcUqk59/docs/images/token-vault/access_token_exchange_flow_diagram.png?fit=max&auto=format&n=78hG6sVmUVcUqk59&q=85&s=5448b94c3101b8b74a3c9cef52f07a25" alt="" width="1322" height="794" data-path="docs/images/token-vault/access_token_exchange_flow_diagram.png" />
</Frame>

実際の例で見ていきましょう。ユーザーが SPA を使って自分の Google カレンダーにミーティングを予定として登録しようとしているケースを考えます。

<div id="prerequisites">
  ## 前提条件
</div>

作業を開始する前に、[Token Vault でアクセストークン交換を設定](/docs/ja-JP/secure/tokens/token-vault/configure-token-vault#configure-access-token-exchange)しておく必要があります。

<div id="step-1-connect-and-authorize-access">
  ## ステップ 1: 接続してアクセスを許可する
</div>

ミーティングをスケジュールするために、SPA は Auth0 経由で Google に接続し、その後 Google Calendar API へのアクセスについてユーザーから許可を得る必要があります。
ユーザーは、[Connected Accounts フロー](/docs/ja-JP/secure/tokens/token-vault/connected-accounts-for-token-vault#how-it-works) を使用して Google 経由でアプリケーションにログインします。このフローは [My Account API](/docs/ja-JP/manage-users/my-account-api) を利用します。

My Account API が Connected Accounts リクエストを検証して完了すると、要求されたカレンダー用のスコープを持つ Google のアクセストークンとリフレッシュトークンを Token Vault に保存します。

<div id="step-2-spa-calls-backend-api-with-auth0-access-token">
  ## ステップ 2: SPA が Auth0 アクセストークンを使ってバックエンド API を呼び出す
</div>

SPA がバックエンド API を呼び出すとき、`Authorization` ヘッダーで Auth0 アクセストークンをバックエンド API に渡します。バックエンド API は、次の内容を確認することで Auth0 アクセストークンを検証します。

* 署名: Auth0 の公開鍵を使用してトークンの署名を検証します。これにより、Auth0 がアクセストークンを発行したことを確認します。
* 発行者: トークンのペイロード内の `iss` クレームを確認し、そのトークンが自分の Auth0 テナントによって発行されたことを確認します。
* オーディエンス: `aud` クレームを確認し、それがバックエンド API 自身の一意の識別子と一致していることを確認します。これにより、そのトークンがこのリソースサーバー向けに発行されたものであることを確認します。
* 有効期限: `exp` クレームを検証し、トークンがまだ有効であり、有効期限切れになっていないことを確認します。
* スコープ: `scope` クレームを確認し、ユーザーに付与されている権限を判定します。

これらの検証にすべて成功すると、バックエンド API は Auth0 アクセストークンを信頼し、トークン交換を続行できます。

<div id="step-3-backend-api-performs-access-token-exchange">
  ## ステップ 3: バックエンド API がアクセストークンを交換する
</div>

アクセストークンを交換するには、バックエンド API にリンクされた [Custom API Client を作成](/docs/ja-JP/secure/tokens/token-vault/configure-token-vault#create-custom-api-client) する必要があります。Custom API Client はバックエンド API と同じ識別子を持ち、Token Vault のグラントタイプが有効になっています。

バックエンド API がアクセストークンの交換を行う際、Auth0 Dashboard に登録されているものと同じエンティティであることを証明するために、Custom API Client のクレデンシャルを Auth0 認可サーバーに渡して自らを認証します。

アクセストークンの交換を行うために、バックエンド API は Auth0 のソフトウェア開発キット (SDK) を使用して `/oauth/token` エンドポイントに対して `POST` リクエストを送信します。

トークンリクエストにおいて、バックエンド API は次のことを行います。

* 自身を認証するために、バックエンド API（Custom API Client）のクライアントクレデンシャルを Auth0 認可サーバーに渡します。
* Auth0 のアクセストークンを Google のアクセストークンに交換します。

```bash lines theme={null}
curl --request POST 'https://{yourDomain}/oauth/token' \
  --header 'Content-Type: application/json' \
  --data '{
    "client_id": "<YOUR_CUSTOM_API_CLIENT_ID>",
    "client_secret": "<YOUR_CUSTOM_API_CLIENT_SECRET>",
    "subject_token": "<YOUR_AUTH0_ACCESS_TOKEN>",
    "grant_type": "urn:auth0:params:oauth:grant-type:token-exchange:federated-connection-access-token",
    "subject_token_type": "urn:ietf:params:oauth:token-type:access_token",
    "requested_token_type": "http://auth0.com/oauth/token-type/federated-connection-access-token",
    "connection": "google-oauth2"
  }'
```

<table class="table">
  <thead>
    <tr>
      <th><strong>パラメーター</strong></th>
      <th><strong>説明</strong></th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>grant\_type</code></td>
      <td>grant タイプ。Token Vault の場合は <code>urn:auth0:params:oauth:grant-type:token-exchange:federated-connection-access-token</code> を設定します。</td>
    </tr>

    <tr>
      <td><code>client\_id</code></td>
      <td>クライアントアプリケーションの ID。</td>
    </tr>

    <tr>
      <td><code>client\_secret</code></td>
      <td>クライアントシークレット。<strong>注:</strong> 外部プロバイダーのアクセストークンを取得するために、任意のクライアント認証方法を使用できます。</td>
    </tr>

    <tr>
      <td><code>subject\_token\_type</code></td>
      <td>subject トークンの種類。アクセストークンの交換では、アクセストークンを指定します: <code>urn:ietf:params:oauth:token-type:access\_token</code>。</td>
    </tr>

    <tr>
      <td><code>subject\_token</code></td>
      <td>Auth0 認可サーバーがユーザーを識別するために検証する Auth0 のアクセストークン。</td>
    </tr>

    <tr>
      <td><code>requested\_token\_type</code></td>
      <td>要求されるトークンの種類。Token Vault の場合は、外部プロバイダーのアクセストークン、または <code>[http://auth0.com/oauth/token-type/federated-connection-access-token](http://auth0.com/oauth/token-type/federated-connection-access-token)</code> を設定します。</td>
    </tr>

    <tr>
      <td><code>connection</code></td>
      <td>接続名。この例では <code>google-oauth2</code>。</td>
    </tr>

    <tr>
      <td><code>login\_hint</code></td>
      <td>(任意) ユーザーが同じ接続から複数のアカウント (仕事用 Google アカウントと個人用 Google アカウントなど) を持っている場合にのみ `login_hint` を使用します。トークン交換時に `login_hint` に値を渡すと、そのユーザーの複数のリンク済みアカウントのうち、どのアカウントに対するリクエストかを明示的に指定することになります。</td>
    </tr>
  </tbody>
</table>

<div id="step-4-auth0-authorization-server-validates-access-token">
  ## ステップ 4: Auth0 認可サーバーがアクセストークンを検証する
</div>

Auth0 認可サーバーは、Auth0 アクセストークンに関連付けられているユーザープロファイルを検証して読み込みます。

* Auth0 は、アクセストークンの `audience` で識別されるバックエンド API に対して、アクセストークン交換リクエストを行っているクライアントが紐付けられていることを検証します。
* Auth0 は、ユーザープロファイルの `connected_accounts` 配列に、認可リクエストで渡された接続名を持つユーザーアカウントが含まれているかどうかを確認します。
* 認可リクエストに `login_hint` が含まれている場合、Auth0 は接続名と `login_hint` の両方に一致するアイデンティティを検索します。
* Auth0 がユーザーを見つけられない場合、`401` ステータスコードとエラーメッセージを返します。

Auth0 認可サーバーがユーザーを検証すると、Token Vault 内の Google アクセストークンを検索します。まだ有効な場合、Auth0 はそのスコープと有効期限と共に Google アクセストークンを返します。

```json lines theme={null}
{
  "access_token": "<YOUR_GOOGLE_ACCESS_TOKEN>",
  "scope": "https://www.googleapis.com/auth/calendar https://www.googleapis.com/auth/calendar.addons.execute https://www.googleapis.com/auth/calendar.events https://www.googleapis.com/auth/calendar.events.readonly https://www.googleapis.com/auth/calendar.settings.readonly https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile openid",
  "expires_in": 1377,
  "issued_token_type": "http://auth0.com/oauth/token-type/federated-connection-access-token",
  "token_type": "Bearer"
}
```

Google のアクセストークンを使って、バックエンド API がユーザーに代わって Google Calendar API を呼び出し、ミーティングをスケジュールします。
