> ## Documentation Index
> Fetch the complete documentation index at: https://docs-dev-docs-event-stream-action-templates.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# カスタムデータベースのアクションスクリプトのベストプラクティス

> カスタムデータベースアクションスクリプトの実行に関するベストプラクティスについて説明します。

カスタムのデータベース接続タイプにより、Auth0がレガシーのidentity storeとやり取りするために使用するカスタムコードが含まれるアクションスクリプトを構成できます。アクションスクリプトは、事前に定義されたパラメーターのセットを受け付ける、名前が付けられたJavaScript関数です。

## Webtaskコンテナー

アクションスクリプトは、約20秒の実行制限で、個々のWebtaskコンテナー内で実行します。関数が実行された後、コンテナーはリサイクルされます。

コンテナーがリサイクルされる時、アクションスクリプトの保留中の操作は終了されます。これにより、エラー条件が返され、`global`オブジェクトのリセットの可能性をもたらす場合があります。`global`オブジェクトの詳細については、[カスタムデータベースのアクションスクリプト環境のベストプラクティス](/docs/ja-jp/authenticate/database-connections/custom-db/custom-database-connections-scripts/environment)をご覧ください。

## 非同期関数

[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)オブジェクトおよび[async function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function)を含む、JavaScriptの非同期関数はアクションスクリプトでサポートされています。

アクションスクリプト内でノンブロッキング操作を実行するために、非同期関数を使用できますが、これらの操作がWebtaskコンテナーの実行制限を超えないことを確認してください。Webtaskコンテナーがリサイクルされる時、保留中の操作は終了されるため、予期しない動作またはエラーを引き起こすことがあります。

アクションスクリプト内で外部サービスまたはAPIを呼び出す場合は、合理的な時間の後にタイムアウトして、かつ外部サービスもしくはAPIに到達できなかった場合は[エラーを返す](#error-handling)ように関数を設定してください。

### 例

Auth0は、アクションスクリプト内での[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)オブジェクトおよび[async function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function)の使用をサポートしています。

#### Promiseオブジェクト

この例では、[promiseチェーン](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises#chaining)を使用して書かれた、ネットワークからリソースを取得しPromiseオブジェクトを返す、ビルトインのJavaScript `fetch`メソッドを使用しています。

```javascript lines expandable theme={null}
function login(userNameOrEmail, password, callback) {
	const hashedPassword = hash(password);
	const apiEndpoint = 'https://example.com/api/authenticate';
	const options = {
		method: 'POST',
		body: {
			email: userNameOrEmail,
			password: hashedPassword
		}
	};

	fetch(apiEndpoint, options) 
		.then((response) => {
			if (!response.ok) {
				return callback(new Error(`HTTP error! Status: ${response.status}`));
			}

			return response.json();
		})
		.then((response) => {
			if (response.err) {
				return callback(new Error(`Error authenticating user: ${err}`));
			}

			let profile = {
				email: response.profileData.email,
				username: response.profileData.username
			};

			return callback(null, profile);
		})
		.catch((err) => {
			return callback(new Error(`An error occurred: ${err}`));
		});
  }
```

#### Async function（非同期関数）

この例では、[async function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function)を使用して書かれた、ネットワークからリソースを取得しPromiseオブジェクトを返す、組み込みのJavaScript `fetch`メソッドを使用しています。

```js lines expandable theme={null}
async function login(userNameOrEmail, password, callback) {
	const hashedPassword = hash(password);
	const apiEndpoint = 'https://example.com/api/authenticate';
	const options = {
		method: 'POST',
		body: {
			email: userNameOrEmail,
			password: hashedPassword
		}
	};

	const response = await fetch(apiEndpoint, options);

	if (!response.ok) {
		return callback(new Error(`HTTP error! Status: ${response.status}`));
	}

	const result = response.json();

	if (result.err) {
		return callback(new Error(`Error authenticating user: ${err}`));
	}

	let profile = {
		email: response.profileData.email,
		username: response.profileData.username
	};

	return callback(null, profile);
}
```

## コールバック関数

`callback`関数は、アクションスクリプトの操作が完了したことを知らせ、一度だけ呼び出さなければなりません。アクションスクリプトは、できれば`return`文を明示的に使用して、`callback`関数の呼び出し後すぐに完了しなければなりません。

<Warning>
  `callback`関数を複数回呼び出すと、予期しない結果が得られたり、エラーが発生したりする可能性があります。

  `callback`関数が一度も呼び出されないと、アクションスクリプトの実行が停止され、Webtaskコンテナのリサイクル時にエラーが返されます。
</Warning>

### 非同期処理

アクションスクリプトが非同期処理を使用する場合は、`callback`関数は、すべての非同期操作が完了した後に呼び出されなければなりません。

### パラメーター

`callback`関数がパラメーターなしで呼び出された場合は、`null`パラメーターが指定されているように実行されます。

## Size（サイズ）

アクションスクリプトの実装の合計サイズは、100kBを超えてはなりません。このサイズ制限は、インポートされた`npm`モジュールを除外します。`npm`モジュールの詳細については、[カスタムデータベースのアクションスクリプト環境のベストプラクティス](/docs/ja-jp/authenticate/database-connections/custom-db/custom-database-connections-scripts/environment)をご覧ください。

スクリプトのサイズが大きくなればなるほど、Webtaskプラットフォームが使用するパッケージングおよび転送プロセスに基づいて遅延が増えます。サイズは、システムのパフォーマンスに影響を与えます。

## 無名関数

アクションスクリプトは無名関数として実装できますが、そうすることをお勧めしていません。無名関数は、アクションスクリプトのデバッグおよび例外的なエラー条件の結果として生成されたコールスタックの解釈を困難にします。無名関数についての詳細は、[MDN Web DocsのIIFE](https://developer.mozilla.org/en-US/docs/Glossary/IIFE)をご覧ください。

## エラー処理

エラーを説明するメッセージで、`Error`オブジェクトを`callback`関数に渡します。

```js lines theme={null}
return callback(new Error('My custom error message'));
```

## セキュリティ

### データベースインターフェイス vs.API

Auth0とレガシーのidentity store間の通信すべての安全を確保してください。レガシーのidentity storeにまだAPIが実装されていない場合は、そうすることを強くお勧めします。

レガシーのidentity storeにAPIが用意されている場合は、Auth0を通して[APIを登録](https://auth0.com/docs/get-started/auth0-overview/set-up-apis)し、エンドユーザーからのアクセスを制限するために[アクションを作成](https://auth0.com/docs/manage-users/access-control/sample-use-cases-actions-with-authorization#deny-access-to-anyone-calling-an-api)してください。

レガシーのidentity storeにAPIが用意されておらず、かつ実装することが不可能な場合でも、データベースと直接通信することができます。Auth0からのインバウンドトラフィックを許可するために、必ず[ファイアウォールの許可リストにAuth0 IPアドレスを追加](https://auth0.com/docs/secure/security-guidance/data-security/allowlist)してください。

## IDプロバイダーのトークン

`user`オブジェクトが`access_token`および`refresh_token`プロパティを返した場合、Auth0は、別の種類のユーザー情報とは異なる方法でそれらを処理します。Auth0は、それらを`user`オブジェクトの`identities`プロパティに保存します。

```json lines theme={null}
{
  "email": "you@example.com",
  "updated_at": "2019-03-15T15:56:44.577Z",
  "user_id": "auth0|some_unique_id",
  "nickname": "a_nick_name",
  "identities": [
    {
      "user_id": "some_unique_id",
      "access_token": "e1b5.................92ba",
      "refresh_token": "a90c.................620b",
      "provider": "auth0",
      "connection": "custom_db_name",
      "isSocial": false
    }
  ],
  "created_at": "2019-03-15T15:56:44.577Z",
  "last_ip": "192.168.1.1",
  "last_login": "2019-03-15T15:56:44.576Z",
  "logins_count": 3
}
```

Auth0管理APIでこれらのプロパティのうちのどちらかを取得したい場合は、[アクセストークンを要求](https://auth0.com/docs/secure/tokens/access-tokens/get-management-api-access-tokens-for-production)するときに、`read:user_idp_tokens`スコープを含めてください。
