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

> Hooks を Client Credentials Exchange 拡張ポイントで使用する方法を説明します。この拡張ポイントは、データベース接続とパスワードレス接続で利用できます。

# Client Credentials Exchange

<Warning>
  Rules と Hooks のサポート終了 (EOL) 日は **2026 年 11 月 18 日** です。また、**2023 年 10 月 16 日** 以降に作成された新規テナントでは、これらは利用できません。アクティブな Hooks を使用している既存のテナントでは、EOL まで Hooks へのアクセスが維持されます。

  Auth0 を拡張する場合は、Actions の使用を強くお勧めします。Actions では、豊富な型情報、インラインドキュメント、公開 `npm` パッケージを利用できるほか、外部連携にも接続できるため、拡張機能の開発体験が向上します。Actions の詳細については、[Understand How Auth0 Actions Work](/ja/docs/customize/actions/actions-overview) を参照してください。

  移行を支援するために、[Rules から Actions への移行](/ja/docs/customize/actions/migrate/migrate-from-rules-to-actions) および [Hooks から Actions への移行](/ja/docs/customize/actions/migrate/migrate-from-hooks-to-actions) のガイドを提供しています。また、機能比較、[Actions のデモ](https://www.youtube.com/watch?v=UesFSY1klrI)、および移行に役立つその他のリソースを紹介した専用の [Move to Actions](https://auth0.com/extensibility/movetoactions) ページも用意しています。

  Rules と Hooks の非推奨化の詳細については、ブログ記事 [Preparing for Rules and Hooks End of Life](https://auth0.com/blog/preparing-for-rules-and-hooks-end-of-life/) を参照してください。
</Warning>

Client Credentials Exchange 拡張ポイントでは、Hooks を使用して、Client Credentials Flow により Authentication API の [`POST /oauth/token` endpoint](https://auth0.com/docs/api/authentication#client-credentials-flow) から <Tooltip tip="アクセストークン: API へのアクセスに使用される、不透明な文字列または JWT 形式の認可資格情報。" cta="用語集を表示" href="/ja/docs/glossary?term=Access+Token">アクセストークン</Tooltip> が発行される際に、カスタム処理を実行できます。たとえば、トークンの発行を拒否したり、アクセストークンにカスタムクレームを追加したり、スコープを変更したりできます。詳細については、[Client Credentials Flow](/ja/docs/get-started/authentication-and-authorization-flow/client-credentials-flow) を参照してください。

この拡張ポイントの Hooks はブロッキング (同期) です。つまり、トリガー処理の一部として実行され、Hook が完了するまで Auth0 パイプラインの残りの処理は実行されません。

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  Client Credentials Exchange 拡張ポイントの `triggerId` は `credentials-exchange` です。この拡張ポイント用の Hooks の作成方法については、[Create Hooks](/ja/docs/customize/hooks/create-hooks) を参照してください。
</Callout>

他の拡張ポイントについては、Extensibility Points を参照してください。

<div id="starter-code-and-parameters">
  ## スターターコードとパラメーター
</div>

Client Credentials Exchange の拡張ポイントで実行される Hook を作成する際には、以下のスターターコードが参考になります。Hook 関数に渡して使用できるパラメーターは、コードサンプルの冒頭に記載されています。

```javascript lines expandable theme={null}
/**
@param {object} client - クライアント情報
@param {string} client.name - クライアント名
@param {string} client.id - クライアントID
@param {string} client.tenant - Auth0 テナント名
@param {object} client.metadata - クライアントメタデータ
@param {array|undefined} scope - トークンのスコープクレームを表す文字列の配列、またはundefined
@param {string} audience - トークンのオーディエンスクレーム
@param {object} context - Auth0 コンテキスト情報
@param {object} context.webtask - Hook (webtask) コンテキスト
@param {function} cb - function (error, accessTokenClaims)
*/

module.exports = function(client, scope, audience, context, cb) {
  var access_token = {};
  access_token.scope = scope; // この行は削除しないでください

  // スコープを変更するか、追加のクレームを付与する
  // access_token['https://example.com/claim'] = 'bar';
  // access_token.scope.push('extra');

  // トークンを拒否し、OAuth2 エラーレスポンスを返す
  // if (denyExchange) {
  //   // HTTP 400 を返す場合: { "error": "invalid_scope", "error_description": "Not authorized for this scope." }
  //   return cb(new InvalidScopeError('Not authorized for this scope.'));
  //
  //   // HTTP 400 を返す場合: { "error": "invalid_request", "error_description": "Not a valid request." }
  //   return cb(new InvalidRequestError('Not a valid request.'));
  //
  //   // HTTP 500 を返す場合: { "error": "server_error", "error_description": "A server error occurred." }
  //   return cb(new ServerError('A server error occurred.'));
  // }

  cb(null, access_token);
};
```

次の点に注意してください。

* サンプルコードの末尾にあるコールバック関数 (`cb`) は処理完了を示すためのもので、必ず含める必要があります。

* `access_token.scope = scope` の行により、付与されたすべてのスコープがアクセストークンに含まれるようになります。これを削除すると、すべてのスコープがリセットされ、トークンにはスクリプトで追加したスコープのみが含まれます。

<div id="default-response">
  ### デフォルトのレスポンス
</div>

Client Credentials Exchange 拡張ポイントで Hook を実行すると、デフォルトのレスポンスオブジェクトは次のとおりです。

```json lines theme={null}
{
  "scope": "array of strings"
}
```

<div id="starter-code-response">
  ### スターターコードのレスポンス
</div>

スコープと追加のクレームを反映するようにスターターコードをカスタマイズしたら、Hook Editor に組み込まれているランナーを使って Hook をテストできます。このランナーは、Client Credentials Exchange で取得されるものと同じボディとレスポンスで Hook 呼び出しをシミュレートします。

<Warning>
  ランナーを使ってコードを実行するには、先に保存する必要があります。保存すると、元のコードは上書きされます。
</Warning>

スターターコードに基づく Hook を実行すると、レスポンスオブジェクトは次のようになります。

```json lines theme={null}
{
  "audience": "https://my-tenant.auth0.com/api/v2/",
  "client": {
    "id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "name": "client-name",
    "tenant": "my-tenant",
    "metadata": {
      "plan": "full"
    }
  },
  "scope": [
    "read:connections"
  ]
}
```

<div id="sample-script-add-an-additional-scope-to-the-access-token">
  ## サンプルスクリプト: アクセストークンに追加のスコープを加える
</div>

この例では、Hook を使用して、アクセストークンにすでに含まれているスコープに追加のスコープを加えます。

```js lines theme={null}
module.exports = function(client, scope, audience, context, cb) {
    // 追加するスコープ
    var access_token = {};

    // アクセストークンに現在設定されているスコープを取得し、
    // 処理対象のオブジェクトに追加する
    // この行は削除しないこと！
    access_token.scope = scope;

    // `read:resource` スコープを追加する
    access_token.scope.push('read:resource');

    // 処理完了を通知し、新しいスコープの配列を返すコールバック
    cb(null, access_token);
};
```

詳しくは、[スコープ](/ja/docs/get-started/apis/scopes)を参照してください。

<div id="response">
  ### レスポンス
</div>

この Hook を実行したときのレスポンスオブジェクトは、次のとおりです。

```json lines theme={null}
{
  "scope": [
    "read:connections",
    "read:resource"
  ]
}
```

<div id="sample-script-add-a-claim-to-the-access-token">
  ## サンプルスクリプト: アクセストークンにクレームを追加する
</div>

この例では、名前空間付きのカスタムクレームとその値をアクセストークンに追加します。詳細については、[名前空間付きカスタムクレームの作成](/ja/docs/secure/tokens/json-web-tokens/create-custom-claims)を参照してください。

発行されたトークンには、次の項目をクレームとして追加できます。

* レスポンスオブジェクトの `scope` プロパティ
* 名前空間付きのプロパティ名を持つ任意のプロパティ

この拡張ポイントでは、レスポンスオブジェクトのその他すべてのプロパティは無視されます。

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  フック内から設定済みの Hook Secret にアクセスするには、`context.webtask.secrets.SECRET_NAME` を使用します。
</Callout>

```js lines theme={null}
module.exports = function(client, scope, audience, context, cb) {
    // 追加するクレーム
    var access_token = {};

    // トークンに追加する新しいクレーム
    access_token['https://example.com/foo'] = 'bar';

    // 完了を示し、新しいクレームを返すコールバック
    cb(null, access_token);
  };
```

<div id="response">
  ### レスポンス
</div>

この Hook を実行すると、レスポンスオブジェクトは次のようになります。

```json lines theme={null}
{
  "https://example.com/foo": "bar"
}
```

<div id="sample-script-raise-an-error-or-deny-an-access-token">
  ## サンプルスクリプト: エラーを発生させる、またはアクセストークンを拒否する
</div>

この例では、カスタム Error オブジェクトを使用して OAuth2 のエラーレスポンスを生成します。 (詳細については、[IETF Datatracker の OAuth2 RFC - Section 5.2](https://tools.ietf.org/html/rfc6749#section-5.2)を参照してください。)

次のように、通常の JavaScript エラーがコールバックで返された場合:

```js lines theme={null}
module.exports = function(client, scope, audience, context, cb) {
    // 完了を示し、新しいクレームを返すコールバック
    cb(new Error("Unknown error occurred.");
  };
```

次に、`/oauth/token` エンドポイントに `client_credentials` グラントをリクエストすると、Auth0 は次のように応答します。

```json lines theme={null}
HTTP 500
{ "error": "server_error", "error_description": "Unknown error occurred." }
```

ただし、OAuth2 エラーレスポンスをより細かく制御したい場合は、代わりに 3 つのカスタム Error オブジェクトを使用できます。

<div id="invalidscopeerror">
  ### InvalidScopeError
</div>

```js lines theme={null}
module.exports = function(client, scope, audience, context, cb) {
    const invalidScope = ...; // スコープが有効かどうかを確認する

    if(invalidScope) {
      cb(new InvalidScopeError("Scope is not permitted."));
    }
  };
```

次に、`/oauth/token` エンドポイントに `client_credentials` グラントをリクエストすると、Auth0 は次のように応答します:

```json lines theme={null}
HTTP 400
{ "error": "invalid_scope", "error_description": "Scope is not permitted." }
```

<div id="invalidrequesterror">
  ### InvalidRequestError
</div>

```js lines theme={null}
module.exports = function(client, scope, audience, context, cb) {
    const invalidRequest = ...; // リクエストが有効かどうかを判定する

    if(invalidRequest) {
      cb(new InvalidRequestError("Bad request."));
    }
  };
```

その後、`/oauth/token` エンドポイントに `client_credentials` グラントをリクエストすると、Auth0 は次のように応答します。

```json lines theme={null}
HTTP 400
{ "error": "invalid_request", "error_description": "Bad request." }
```

<div id="servererror">
  ### ServerError
</div>

```js lines theme={null}
module.exports = function(client, scope, audience, context, cb) {
    callOtherService(function(err, response) {
      if(err) {
        return cb(new ServerError("Error calling remote system: " + err.message));
      }
    });
  };
```

その後、`/oauth/token` エンドポイントに `client_credentials` グラントを要求すると、Auth0 から次の応答が返されます。

```json lines theme={null}
HTTP 400
{ "error": "server_error", "error_description": "Error calling remote system: ..." }
```

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  現時点では、組み込みの JavaScript `Error` クラスと `ServerError` の動作は同じですが、`ServerError` クラスを使用すると、返される OAuth2 エラーを明示的に指定できます。
</Callout>

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