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

# Client Credentials Exchange

> データベース接続およびパスワードレス接続に利用可能なClient Credentials Exchange（クライアント資格情報交換）拡張ポイントでフックを使用する方法を説明します。

<Warning>
  RulesとHooksのサポート終了（EOL）日は**2026年11月18日** であり、**2023年10月16** 日の時点で作成された新しいテナントは使用できなくなります。Hooksが有効な既存のテナントは、サポート終了までHooksを利用できます。

  今後はActionsに移行して、Auth0の機能を拡張することを強くお勧めします。Actionsを使用すると、豊富な情報やインラインドキュメント、パブリック`npm`パッケージにアクセスして、外部統合を使って全体的な拡張エクスペリエンスを強化することができます。Actionsの詳細については、「[Auth0 Actionsの仕組みを理解する](/docs/ja-jp/customize/actions/actions-overview)」をお読みください。

  当社では、移行の参考資料として、[RulesからActionsへの移行](/docs/ja-jp/customize/actions/migrate/migrate-from-rules-to-actions)と[HooksからActionsへの移行](/docs/ja-jp/customize/actions/migrate/migrate-from-hooks-to-actions)に関するガイドを提供しています。また、専用の「[Actionsへの移行](https://auth0.com/extensibility/movetoactions)」ページでは、機能の比較や[Actionsのデモ](https://www.youtube.com/watch?v=UesFSY1klrI)、その他のリソースを掲載して、円滑な移行をサポートしています。

  RulesとHooksの廃止の詳細については、当社のブログ記事「[RulesとHooksの提供終了について](https://auth0.com/blog/preparing-for-rules-and-hooks-end-of-life/)」をお読みください。
</Warning>

Client Credentials Exchange（クライアント資格情報交換）拡張ポイントでは、フックにより、クライアントの資格情報フローを使用して認証APIの[`POST /oauth/token`エンドポイント](/docs/ja-jp/api/authentication#client-credentials-flow)からアクセストークンが発行される際にカスタムアクションを実行できます。たとえば、トークンが発行されないように拒否する、アクセストークンにカスタムクレームを追加する、またはそのスコープを修正することができます。詳細については、「[クライアントの資格情報フロー](/docs/ja-jp/get-started/authentication-and-authorization-flow/client-credentials-flow)」をお読みください。

この拡張ポイントでのフックはブロッキング（同期的）であり、トリガーのプロセスの一部として実行されます。そのため、フックが完了するまでAuth0パイプラインの他の部分の実行が停止されます。

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  Client Credentials Exchange（クライアント資格情報交換）拡張ポイントの`triggerId`は、`credentials-exchange`です。この拡張ポイントに対してフックを作成する方法については、「[フックを作成する](/docs/ja-jp/customize/hooks/create-hooks)」をお読みください。
</Callout>

## スターターコードとパラメーター

Client Credentials Exchange（クライアント資格情報交換）拡張ポイントで実行されるフックを作成する際、以下のスターターコードが役立つかもしれません。Hook関数に渡され、使用されることができるパラメーターは、コード例の最上部にリストされています。

```javascript lines theme={null}
/**
@param {object} client - client information
@param {string} client.name - client name
@param {string} client.id - client ID
@param {string} client.tenant - Auth0 tenant name
@param {object} client.metadata - client metadata
@param {array|undefined} scope - either an array of strings representing the token's scope claim, or undefined
@param {string} audience - token's audience claim
@param {object} context - Auth0 context info
@param {object} context.webtask - Hook (webtask) context
@param {function} cb - function (error, accessTokenClaims)
*/

module.exports = function(client, scope, audience, context, cb) {
  var access_token = {};
  access_token.scope = scope; // do not remove this line

  // Modify scopes or add extra claims
  // access_token['https://example.com/claim'] = 'bar';
  // access_token.scope.push('extra');

  // Deny the token and respond with an OAuth2 error response
  // if (denyExchange) {
  //   // To return an HTTP 400 with { "error": "invalid_scope", "error_description": "Not authorized for this scope." }
  //   return cb(new InvalidScopeError('Not authorized for this scope.'));
  //
  //   // To return an HTTP 400 with { "error": "invalid_request", "error_description": "Not a valid request." }
  //   return cb(new InvalidRequestError('Not a valid request.'));
  //
  //   // To return an HTTP 500 with { "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`という行は、すべての付与されたスコープがアクセストークンに存在するようにします。それを取り除くとすべてのスコープをリセットすることになり、トークンにはスクリプトで追加したスコープのみ含まれます。

### デフォルトの応答

Client Credentials Exchange（クライアント資格情報交換）拡張ポイントでフックを実行すると、デフォルトの応答オブジェクトは次のようになります。

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

### スターターコードの応答

スコープと追加クレームを使用してスターターコードをカスタマイズしたら、Hookエディタに埋め込まれたランナーを使用してフックをテストできます。ランナーは、Client Credentials Exchange（クライアント資格情報交換）で得られるものと同じ要求ボディと応答を使ってフックへの呼び出しをシミュレートします。

<Warning>
  ランナーを使用してコードを実行するには、保存が必要なため、元のコードは上書きされます。
</Warning>

スターターコードに基づいたフックを実行する場合、応答オブジェクトは以下の通りになります。

```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"
  ]
}
```

## スクリプト例：アクセストークンに追加スコープを追加する

この例では、既存のスコープに加えてアクセストークンに追加のスコープを付与するためにフックを使用します。

```javascript lines theme={null}
module.exports = function(client, scope, audience, context, cb) {
    // Scopes to be added
    var access_token = {};

    // Get the scope that's currently on the Access Token
    // and add it to the object we're working with
    // Do not remove this line!
    access_token.scope = scope;

    // Append the `read:resource` scope
    access_token.scope.push('read:resource');

    // Callback to indicate completion and to return new
    // array of scopes
    cb(null, access_token);
};
```

詳しくは、「[スコープ](/docs/ja-jp/get-started/apis/scopes)」をお読みください。

### 応答

このフックを実行すると、応答オブジェクトは次のようになります。

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

## スクリプト例：アクセストークンにクレームを追加する

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

以下をクレームとして発行済みトークンに追加できます。

* 応答オブジェクトの`scope`プロパティ
* 名前空間プロパティ名のあるすべてのプロパティ

拡張ポイントは、その他すべての応答オブジェクトプロパティを無視します。

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  構成されたフックシークレットにフック内からアクセスするには、`context.webtask.secrets.SECRET_NAME`を使用します。
</Callout>

```javascript lines theme={null}
module.exports = function(client, scope, audience, context, cb) {
    // Claims to be added
    var access_token = {};

    // New claim to add to the token
    access_token['https://example.com/foo'] = 'bar';

    // Callback to indicate completion and to return new claim
    cb(null, access_token);
  };
```

### 応答

このフックを実行すると、応答オブジェクトは次のようになります。

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

## スクリプト例：エラーを発生させる、またはアクセストークンを拒否する

この例では、カスタムのエラーオブジェクトを使用して、OAuth2エラー応答を生成します（詳細については、[IETF DatatrackerのOAuth2 RFC、セクション5.2](https://tools.ietf.org/html/rfc6749#section-5.2)をお読みください）。

コールバック内で次のような単純なJavaScriptエラーが返された場合に、

```javascript lines theme={null}
module.exports = function(client, scope, audience, context, cb) {
    // Callback to indicate completion and to return new claim
    cb(new Error("Unknown error occurred.");
  };
```

`/oauth/token`エンドポイントから`client_credentials`の付与を要求すると、Auth0は次のように応答します。

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

しかし、OAuth2エラー応答をさらに制御したい場合は、3種類のカスタムエラーオブジェクトを使用することもできます。

### InvalidScopeError

```javascript lines theme={null}
module.exports = function(client, scope, audience, context, cb) {
    const invalidScope = ...; // determine if scope is valid

    if(invalidScope) {
      cb(new InvalidScopeError("Scope is not permitted."));
    }
  };
```

そして、`/oauth/token`エンドポイントから`client_credentials`の付与を要求すると、Auth0は次のように応答します。

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

### InvalidRequestError

```javascript lines theme={null}
module.exports = function(client, scope, audience, context, cb) {
    const invalidRequest = ...; // determine if request is valid

    if(invalidRequest) {
      cb(new InvalidRequestError("Bad request."));
    }
  };
```

`/oauth/token`エンドポイントから`client_credentials`の付与を要求すると、Auth0は次のように応答します。

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

### ServerError

```javascript 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は次のように応答します。

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

## もっと詳しく
