テスト用のテナントとアプリケーションを作成
- テストに使用する新しいテナントを作成します。
- Machine-to-Machine アプリケーションを作成します。 Management API のスコープを有効にするとき、およびカスタムデータベースアクションスクリプトを作成するときに、アプリケーションのクライアント ID とシークレットが必要です。
-
このアプリケーションで Password と Client Credential の両方のグラントを有効にします。

- アプリケーションを認可するには、Applications > APIs に移動して Management API を選択します。
- Machine-to-Machine Applications タブで、トグルを使用してテスト用アプリケーションを認可します。
-
ドロップダウンメニューを選択し、次の Auth0 Management API スコープを有効にします。
read:usersupdate:usersdelete:userscreate:usersread:users_app_metadataupdate:users_app_metadatacreate:users_app_metadata
Auth0 へのユーザーインポートを有効にしてテストする
-
Auth0 Dashboard > Authentication > Databaseで、Required Username を有効にしたデータベース接続を2つ作成します。一方はソース、もう一方はターゲットとして使用します。Organizations を使用してテストする場合は、Context object in database scripts を有効にします。
テストで簡単なパスワードを使用できるように、ターゲットデータベースとソースデータベースの両方で Password Policy を Non-empty password required に設定できます。
- ソースデータベース接続にテストユーザーを作成します。Auth0 Dashboard > User Management > Usersで、**+Create User > Create via UI を選択します。 開いた Create user ウィンドウで、Connection にソースデータベース接続を選択します。必要なフィールドに入力し、Create (または Create Another) を選択します。
-
ターゲットデータベース接続を設定します。
- Custom Database タブで、Use my own database を有効にします。
- Settings タブで、Import Users to Auth0 を有効にします。
-
Custom Database タブの Database settings セクションで、ソースデータベース接続から次の情報を追加します。
キー 値 client_id作成したアプリケーションの クライアント ID。 client_secret作成したアプリケーションの Client Secret。 auth0_domainAuth0 ドメイン内のテナント名: yourTenant.us.auth0.com。source_databaseソース接続の名前。
- ターゲットデータベース内の Login および Get User データベースアクションスクリプトを更新します。
-
各スクリプトで Save and Try を選択します。Actions リアルタイムログで
console.log出力を監視します。 - Try Connection を選択して、接続をリアルタイムでテストします。
Import Users to Auth0 を無効にしてテストする
- Dashboard > Authentication > Database で、対象となるテスト用データベース接続を1つ作成します。
-
以下のサンプルを使用して、データベースアクションスクリプトを更新します。
- Get User
- Login
- Create
- Delete
- Verify
- Change Password
- Change Email
次のサンプルでGet User スクリプトを更新します。async function getUser(user, context, callback) { log(`Script started.`); log(`Requesting an Access Token from "${configuration.auth0_domain}".`); let accessToken = await getAccessToken(); accessToken = accessToken.access_token; if (!accessToken) return log(`Failed to get an Access Token from "${configuration.auth0_domain}".`, true); log(`The Access Token is available. Searching for user "${user}" in "${configuration.source_database}"`); user = user.toLowerCase(); const searchQuery = encodeURI(`identities.connection:"${configuration.source_database}"+AND+(email:${user} OR username:${user})`); var options = { method: `GET`, url: `https://${configuration.auth0_domain}/api/v2/users?q=${searchQuery}`, headers: { Authorization: `Bearer ${accessToken}`, } }; request(options, function (error, response) { if (error) return log(`Cannot connect to "${configuration.source_database}" database.`, true); let search_results = JSON.parse(response.body); let profile = null; if (search_results.length > 0) { log(`A user "${user}" is FOUND in "${configuration.source_database}" database.`); profile = { user_id: search_results[0].user_id.toString(), nickname: search_results[0].nickname, username: search_results[0].username, email: search_results[0].email }; } else { log(`A user "${user}" is NOT FOUND in "${configuration.source_database}" database.`); } log(`Script completed!`); return callback(null, profile); }); /* -- クライアント資格情報によるアクセストークンの取得 -- */ async function getAccessToken() { var options = { method: `POST`, url: `https://${configuration.auth0_domain}/oauth/token`, headers: { "Content-Type": `application/x-www-form-urlencoded`, }, form: { grant_type: `client_credentials`, client_id: configuration.client_id, client_secret: configuration.client_secret, audience: `https://${configuration.auth0_domain}/api/v2/` }, json: true }; return new Promise(function (resolve) { request(options, function (error, response) { resolve(error || response.body); }); }); } /* -- ログ -- */ function log(message, error = false) { const script_name = `GET USER`; const error_label = error ? `(ERROR)` : ``; const return_message = `${script_name}: ${error_label} ${message}`; console.log(return_message); if (error) return callback(new Error(return_message)); } }以下のサンプルでLogin スクリプトを更新します。function login(usernameOrEmail, password, context, callback) { log(`Script started.`); const jwt = require('jsonwebtoken'); const options = { method: `POST`, url: `https://${configuration.auth0_domain}/oauth/token`, headers: { "Content-Type": `application/x-www-form-urlencoded` }, json: true, form: { grant_type: `http://auth0.com/oauth/grant-type/password-realm`, client_id: configuration.client_id, client_secret: configuration.client_secret, username: usernameOrEmail, password: password, realm: `${configuration.source_database}` } }; request(options, function (error, response, body) { log(`Attempting to authenticate a user "${usernameOrEmail}" against "${configuration.source_database}" database in "${configuration.auth0_domain}" tenant.`); if (error) return log(`Cannot connect to "${configuration.auth0_domain}" database.`, true); if (response.statusCode !== 200) { console.log(`LOGIN: (ERROR) ${response.body.error_description}`); return callback(new WrongUsernameOrPasswordError(usernameOrEmail, `LOGIN: (ERROR) ${response.body.error_description}`)); } log(`Successfuly authenticated user "${usernameOrEmail}" against "${configuration.source_database}" database in "${configuration.auth0_domain}" tenant.`); const decoded_id_token = jwt.decode(body.id_token); const profile = { user_id: decoded_id_token.sub, nickname: decoded_id_token.nickname, username: decoded_id_token.username, email: decoded_id_token.email }; log(`Script completed.`); return callback(null, profile); }); /* -- ログ -- */ function log(message, error = false) { const script_name = `LOGIN`; const error_label = error ? `(ERROR)` : ``; const return_message = `${script_name}: ${error_label} ${message}`; console.log(return_message); if (error) return callback(new Error(return_message)); } }Create スクリプトを次のサンプルに更新します。async function create(user, context, callback) { log(`Script started.`); log(`Requesting an Access Token from "${configuration.auth0_domain}".`); let accessToken = await getAccessToken(); if (!accessToken.access_token) return log(`Failed to get an Access Token from "${configuration.auth0_domain}".`, true); accessToken = accessToken.access_token; log(`The Access Token is available. Attempting to create a user "${user.email}" in "${configuration.source_database}"`); const options = { method: `POST`, url: `https://${configuration.auth0_domain}/api/v2/users`, headers: { Authorization: `Bearer ${accessToken}`, "Content-Type": `application/x-www-form-urlencoded` }, form: { connection: configuration.source_database, email: user.email, password: user.password, username: user.username }, json: true }; request(options, function (error, response) { if (error) return log(`Cannot connect to "${configuration.source_database}" database.`, true); switch (response.statusCode) { case 201: log(`The user "${user.email}" is successfuly created in "${configuration.source_database}" database.`); return callback(null); case 409: return callback(new ValidationError(`user_exists`, `The user already exists in "${configuration.source_database}" database.`)); default: return log(`Failed to create a user "${user.email}" in "${configuration.source_database}" database. Error: "${response.statusCode}, ${response.body.message}"`, true); } }); /* -- クライアント資格情報によるアクセストークンの取得 -- */ async function getAccessToken() { var options = { method: `POST`, url: `https://${configuration.auth0_domain}/oauth/token`, headers: { "Content-Type": `application/x-www-form-urlencoded`, }, form: { grant_type: `client_credentials`, client_id: configuration.client_id, client_secret: configuration.client_secret, audience: `https://${configuration.auth0_domain}/api/v2/` }, json: true }; return new Promise(function (resolve) { request(options, function (error, response) { resolve(error || response.body); }); }); } /* -- ログ -- */ function log(message, error = false) { const script_name = `CREATE`; const error_label = error ? `(ERROR)` : ``; const return_message = `${script_name}: ${error_label} ${message}`; console.log(return_message); if (error) return callback(new Error(return_message)); } }Delete scriptを次のサンプルに更新します。async function deleteUser(user, context, callback) { log(`Script started.`); log(`Requesting an Access Token from "${configuration.auth0_domain}".`); let accessToken = await getAccessToken(); if (!accessToken.access_token) return log(`Failed to get an Access Token from "${configuration.auth0_domain}".`, true); accessToken = accessToken.access_token; log(`The Access Token is available. Attempting to delete a user "${user}" from "${configuration.source_database}"`); const options = { method: `DELETE`, url: `https://${configuration.auth0_domain}/api/v2/users/${user}`, headers: { Authorization: `Bearer ${accessToken}`, "Content-Type": `application/x-www-form-urlencoded` }, json: true }; request(options, function (error, response) { if (error) return log(`Cannot connect to "${configuration.source_database}" database.`, true); switch (response.statusCode) { case 204: log(`The user "${user}" is successfuly deleted from "${configuration.source_database}" database.`); return callback(null); default: return log(`Failed to delete a user "${user}" from "${configuration.source_database}" database. Error: "${response.statusCode}, ${response.body.message}"`, true); } }); /* -- クライアント資格情報によるアクセストークンの取得 -- */ async function getAccessToken() { var options = { method: `POST`, url: `https://${configuration.auth0_domain}/oauth/token`, headers: { "Content-Type": `application/x-www-form-urlencoded`, }, form: { grant_type: `client_credentials`, client_id: configuration.client_id, client_secret: configuration.client_secret, audience: `https://${configuration.auth0_domain}/api/v2/` }, json: true }; return new Promise(function (resolve) { request(options, function (error, response) { resolve(error || response.body); }); }); } /* -- ログ -- */ function log(message, error = false) { const script_name = `DELETE`; const error_label = error ? `(ERROR)` : ``; const return_message = `${script_name}: ${error_label} ${message}`; console.log(return_message); if (error) return callback(new Error(return_message)); } }Verify スクリプトを以下のサンプルに更新します。async function verify(user, context, callback) { log(`Script started.`); log(`Requesting an Access Token from "${configuration.auth0_domain}".`); let accessToken = await getAccessToken(); if (!accessToken.access_token) return log(`Failed to get an Access Token from "${configuration.auth0_domain}".`, true); accessToken = accessToken.access_token; log(`The Access Token is available. Searching for user "${user}" in "${configuration.source_database}"`); user = user.toLowerCase(); const searchQuery = encodeURI(`identities.connection:"${configuration.source_database}"+AND+(email:${user} OR username:${user})`); var options = { method: `GET`, url: `https://${configuration.auth0_domain}/api/v2/users?q=${searchQuery}`, headers: { Authorization: `Bearer ${accessToken}`, } }; request(options, function (error, response) { if (error) return log(`Cannot connect to "${configuration.source_database}" database.`, true); let search_results = JSON.parse(response.body); if (search_results.length > 0) { log(`A user "${user}" is found in "${configuration.source_database}" database.`); const user_id = search_results[0].user_id.toString(); log(`Attempting to mark user "${user_id}" as verified in "${configuration.source_database}" database`); const options = { method: `PATCH`, url: `https://${configuration.auth0_domain}/api/v2/users/${user_id}`, headers: { Authorization: `Bearer ${accessToken}`, "Content-Type": `application/x-www-form-urlencoded` }, form: { email_verified: true, }, json: true }; request(options, function (error, response) { if (error) return log(`Cannot connect to "${configuration.source_database}" database.`, true); switch (response.statusCode) { case 200: log(`The user "${user}" is marked as verified in "${configuration.source_database}" database.`); return callback(null, true); default: return log(`Failed to mark a user "${user}" as verified in "${configuration.source_database}" database. Error: "${response.statusCode}, ${response.body.message}"`, true); } }); } else { log(`A user "${user}" is not found in "${configuration.source_database}" database. Unable to verify.`, true); } }); /* -- クライアント資格情報によるアクセストークンの取得 -- */ async function getAccessToken() { var options = { method: `POST`, url: `https://${configuration.auth0_domain}/oauth/token`, headers: { "Content-Type": `application/x-www-form-urlencoded`, }, form: { grant_type: `client_credentials`, client_id: configuration.client_id, client_secret: configuration.client_secret, audience: `https://${configuration.auth0_domain}/api/v2/` }, json: true }; return new Promise(function (resolve) { request(options, function (error, response) { resolve(error || response.body); }); }); } /* -- ログ -- */ function log(message, error = false) { const script_name = `VERIFY`; const error_label = error ? `(ERROR)` : ``; const return_message = `${script_name}: ${error_label} ${message}`; console.log(return_message); if (error) return callback(new Error(return_message)); } }Change Password スクリプトを次のサンプルに更新します。async function changePassword(user, newPassword, context, callback) { log(`Script started.`); log(`Requesting an Access Token from "${configuration.auth0_domain}".`); let accessToken = await getAccessToken(); if (!accessToken.access_token) return log(`Failed to get an Access Token from "${configuration.auth0_domain}".`, true); accessToken = accessToken.access_token; log(`The Access Token is available. Searching for user "${user}" in "${configuration.source_database}" database.`); user = user.toLowerCase(); const searchQuery = encodeURI(`identities.connection:"${configuration.source_database}"+AND+(email:${user} OR username:${user})`); var options = { method: `GET`, url: `https://${configuration.auth0_domain}/api/v2/users?q=${searchQuery}`, headers: { Authorization: `Bearer ${accessToken}`, } }; request(options, function (error, response) { if (error) return log(`Cannot connect to "${configuration.source_database}" database.`, true); let search_results = JSON.parse(response.body); if (search_results.length > 0) { log(`A user "${user}" is found in "${configuration.source_database}" database.`); const user_id = search_results[0].user_id.toString(); log(`Attempting to change password for user "${user_id}" in "${configuration.source_database}" database.`); const options = { method: `PATCH`, url: `https://${configuration.auth0_domain}/api/v2/users/${user_id}`, headers: { Authorization: `Bearer ${accessToken}`, "Content-Type": `application/x-www-form-urlencoded` }, form: { password: newPassword, }, json: true }; request(options, function (error, response) { if (error) return log(`Cannot connect to "${configuration.source_database}" database.`, true); switch (response.statusCode) { case 200: log(`The user "${user}" password successfully changed in "${configuration.source_database}" database.`); return callback(null, true); default: return log(`Failed to change password for "${user}" in "${configuration.source_database}" database. Error: "${response.statusCode}, ${response.body.message}"`, true); } }); } else { log(`A user "${user}" is not found in "${configuration.source_database}" database. Unable to change password.`, true); } }); /* -- クライアント資格情報によるアクセストークンの取得 -- */ async function getAccessToken() { var options = { method: `POST`, url: `https://${configuration.auth0_domain}/oauth/token`, headers: { "Content-Type": `application/x-www-form-urlencoded`, }, form: { grant_type: `client_credentials`, client_id: configuration.client_id, client_secret: configuration.client_secret, audience: `https://${configuration.auth0_domain}/api/v2/` }, json: true }; return new Promise(function (resolve) { request(options, function (error, response) { resolve(error || response.body); }); }); } /* -- ログ -- */ function log(message, error = false) { const script_name = `CHANGE PASSWORD`; const error_label = error ? `(ERROR)` : ``; const return_message = `${script_name}: ${error_label} ${message}`; console.log(return_message); if (error) return callback(new Error(return_message)); } }以下のサンプルを使用して、Change Email スクリプトを更新します。async function changeEmail(user, newEmail, verified, callback) { log(`Script started.`); log(`Requesting an Access Token from "${configuration.auth0_domain}".`); let accessToken = await getAccessToken(); if (!accessToken.access_token) return log(`Failed to get an Access Token from "${configuration.auth0_domain}".`, true); accessToken = accessToken.access_token; log(`The Access Token is available. Searching for user "${user}" in "${configuration.source_database}" database.`); user = user.toLowerCase(); const searchQuery = encodeURI(`identities.connection:"${configuration.source_database}"+AND+(email:${user} OR username:${user})`); var options = { method: `GET`, url: `https://${configuration.auth0_domain}/api/v2/users?q=${searchQuery}`, headers: { Authorization: `Bearer ${accessToken}`, } }; request(options, function (error, response) { if (error) return log(`Cannot connect to "${configuration.source_database}" database.`, true); let search_results = JSON.parse(response.body); if (search_results.length > 0) { log(`A user "${user}" is found in "${configuration.source_database}" database.`); const user_id = search_results[0].user_id.toString(); log(`Attempting to change email / verified status for user "${user_id}" in "${configuration.source_database}" database.`); const options = { method: `PATCH`, url: `https://${configuration.auth0_domain}/api/v2/users/${user_id}`, headers: { Authorization: `Bearer ${accessToken}`, "Content-Type": `application/x-www-form-urlencoded` }, form: { email: newEmail, email_verified: verified || false }, json: true }; request(options, function (error, response) { if (error) return log(`Cannot connect to "${configuration.source_database}" database.`, true); switch (response.statusCode) { case 200: log(`The user "${user}" email / verified status successfully changed in "${configuration.source_database}" database.`); return callback(null, true); default: return log(`Failed to change email / verified status for "${user}" in "${configuration.source_database}" database. Error: "${response.statusCode}, ${response.body.message}"`, true); } }); } else { log(`A user "${user}" is not found in "${configuration.source_database}" database. Unable to change email / verified status.`, true); } }); /* -- クライアント資格情報によるアクセストークンの取得 -- */ async function getAccessToken() { var options = { method: `POST`, url: `https://${configuration.auth0_domain}/oauth/token`, headers: { "Content-Type": `application/x-www-form-urlencoded`, }, form: { grant_type: `client_credentials`, client_id: configuration.client_id, client_secret: configuration.client_secret, audience: `https://${configuration.auth0_domain}/api/v2/` }, json: true }; return new Promise(function (resolve) { request(options, function (error, response) { resolve(error || response.body); }); }); } /* -- ログ -- */ function log(message, error = false) { const script_name = `CHANGE EMAIL`; const error_label = error ? `(ERROR)` : ``; const return_message = `${script_name}: ${error_label} ${message}`; console.log(return_message); if (error) return callback(new Error(return_message)); } } -
各スクリプトで保存して試すを選択します。Actions リアルタイムログの
console.log出力を確認してください。 - 接続を試すを選択して、接続をリアルタイムでテストします。