> ## 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>
  ルールおよび Hooks の提供終了 (EOL) 日は **2026年11月18日** です。また、**2023年10月16日** 以降に作成された新規テナントでは、これらはすでに利用できません。既存のテナントで有効な Hooks を使用している場合は、提供終了まで Hooks 機能を引き続き利用できます。

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

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

  ルールおよび 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 拡張ポイントでは、クライアント認証情報フローを使用して Authentication API の [`POST /oauth/token` エンドポイント](https://auth0.com/docs/api/authentication#client-credentials-flow) から <Tooltip tip="Access Token: API にアクセスするために使用される認可資格情報で、不透明な文字列または JWT の形式です。" cta="用語集を見る" href="/docs/ja-jp/glossary?term=Access+Token">Access Token</Tooltip> が発行される際に、Hooks を使ってカスタムアクションを実行できます。たとえば、トークンの発行を拒否したり、Access Token にカスタムクレームを追加したり、scope を変更したりできます。詳しくは、[Client Credentials Flow](/docs/ja-jp/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` です。この拡張ポイント用の Hook を作成する方法については、[Create Hooks](/docs/ja-jp/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 - トークンの audience クレーム
@param {object} context - Auth0 コンテキスト情報
@param {object} context.webtask - フック（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');

  // トークンを拒否して OAuth 2.0 エラーレスポンスを返す
  // 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);
};
```

詳しくは、[スコープ](/docs/ja-jp/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>

この例では、名前空間付きのカスタムクレームとその値をアクセストークンに追加します。詳細については、[Create Namespaced Custom Claims](/docs/ja-jp/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 オブジェクトを使用して、OAuth 2.0 のエラーレスポンスを生成します。 (詳しくは、[IETF Datatracker の OAuth2 RFC - セクション 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." }
```

ただし、OAuth 2.0 のエラーレスポンスをより細かく制御したい場合は、代わりに使用できる 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` クラスを使うと、返される OAuth 2.0 エラーを明示的に指定できます。
</Callout>

<div id="learn-more">
  ## さらに詳しく
</div>
