こんにちは。ゲーソル新屋です。
今回はAuth0のCustom Database Connectionを使って
(1)Auth0から外部DB(Amazon RDS)に接続してユーザー認証
(2)ユーザーを外部DBからAuth0のユーザーストアへ自動移行
をやってみます。
ちなみにユーザー移行手段は全部で3つあります。
・Management API を使用したユーザーの一括インポート
・ユーザーインポート/エクスポートのExtensionを使用してユーザーを移行する
・自動移行(トリクルマイグレーション)←今回検証する機能
では、やっていきます。
(1)Auth0から外部DB(Amazon RDS)に接続してユーザー認証
■Custom Database Connection を新規作成
■Auth0側のIPを控える
■既存DBセットアップ
今回のシナリオの既存DBとしてAmazon RDS(Aurora/MySQL)を新規作成
こちらを参考記事にしました
■Auth0側からのインバウンドアクセスを許可
■既存ユーザーデータ投入
user1〜3のユーザーでパスワード全員同じ 移行済かどうかのフラグをFALSE
にしておく
mysql> select * from users;
+----+-------------------+--------------------------------------------------------------+----------+-------------+
| id | email | password | nickname | is_migrated |
+----+-------------------+--------------------------------------------------------------+----------+-------------+
| 1 | user1@example.com | $2b$10$tiYl9C2I0t1hwuZ9m6IUiea4lgJlDIy/7HFAjTaWkLqfHfARvSfE6 | user1 | 0 |
| 2 | user2@example.com | $2b$10$tiYl9C2I0t1hwuZ9m6IUiea4lgJlDIy/7HFAjTaWkLqfHfARvSfE6 | user2 | 0 |
| 3 | user3@example.com | $2b$10$tiYl9C2I0t1hwuZ9m6IUiea4lgJlDIy/7HFAjTaWkLqfHfARvSfE6 | user3 | 0 |
+----+-------------------+--------------------------------------------------------------+----------+-------------+
テーブル定義はこんな感じ
CREATE TABLE users (
id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
email VARCHAR(50) NOT NULL,
password VARCHAR(100) NOT NULL,
nickname VARCHAR(50),
is_migrated BOOLEAN DEFAULT FALSE,
UNIQUE (email)
);
■Custom Database Connection に既存DBの接続情報を設定
■Database Action Script を実装
まずはLoginだけ テンプレートスクリプトがあるので簡単
コード全体はこんな感じ
function login(email, password, callback) {
const mysql = require('mysql');
const bcrypt = require('bcrypt');
const connection = mysql.createConnection({
host: configuration.TEST_DB_HOST,
user: configuration.TEST_DB_USER,
password: configuration.TEST_DB_PASSWORD,
database: configuration.TEST_DB_DBNAME
});
connection.connect();
const query = 'SELECT id, nickname, email, password FROM users WHERE email = ?';
connection.query(query, [ email ], function(err, results) {
if (err) return callback(err);
if (results.length === 0) return callback(new WrongUsernameOrPasswordError(email));
const user = results[0];
bcrypt.compare(password, user.password, function(err, isValid) {
if (err || !isValid) return callback(err || new WrongUsernameOrPasswordError(email));
callback(null, {
user_id: user.id.toString(),
nickname: user.nickname,
email: user.email
});
});
});
}
■アプリケーションでDatabaseを有効化
■動作確認
ここまでで、Auth0から外部のユーザーストアに接続できることを確認できました。
(2)ユーザーを外部DBからAuth0のユーザーストアへ自動移行
■自動移行を有効化
Database Action Script を修正
Loginの追加コードはこんな感じ
bcrypt.compare(password, user.password, function(err, isValid) {
if (err || !isValid) return callback(err || new WrongUsernameOrPasswordError(email));
// ここから
const query = 'UPDATE users SET is_migrated = true WHERE email = ?';
connection.query(query, [ email ], function(err, results) {
if (err) return callback(err);
});
// ここまで
callback(null, {
Get userのコード全体はこんな感じ
function getByEmail(email, callback) {
const mysql = require('mysql');
const connection = mysql.createConnection({
host: configuration.TEST_DB_HOST,
user: configuration.TEST_DB_USER,
password: configuration.TEST_DB_PASSWORD,
database: configuration.TEST_DB_DBNAME
});
connection.connect();
const query = 'SELECT id, nickname, email FROM users WHERE email = ?';
connection.query(query, [ email ], function(err, results) {
if (err || results.length === 0) return callback(err || null);
const user = results[0];
callback(null, {
user_id: user.id.toString(),
nickname: user.nickname,
email: user.email
});
});
}
■動作確認
ログインを施行したユーザーはマイグレーション済みとなる
mysql> select * from users;
+----+-------------------+--------------------------------------------------------------+----------+-------------+
| id | email | password | nickname | is_migrated |
+----+-------------------+--------------------------------------------------------------+----------+-------------+
| 1 | user1@example.com | $2b$10$tiYl9C2I0t1hwuZ9m6IUiea4lgJlDIy/7HFAjTaWkLqfHfARvSfE6 | user1 | 1 |
| 2 | user2@example.com | $2b$10$tiYl9C2I0t1hwuZ9m6IUiea4lgJlDIy/7HFAjTaWkLqfHfARvSfE6 | user2 | 1 |
| 3 | user3@example.com | $2b$10$tiYl9C2I0t1hwuZ9m6IUiea4lgJlDIy/7HFAjTaWkLqfHfARvSfE6 | user3 | 0 |
+----+-------------------+--------------------------------------------------------------+----------+-------------+
以上です。
まとめ
簡単に外部のユーザーストアと接続できました。Action ScriptはMySQL以外にもテンプレートがあり、ほとんどコードを書かないで設定完了しました。 外部のユーザーストアは何もRDSに限らず、Cognitoユーザープールなんかでも、カスタムデータベース接続できちゃいます。その場合、Action ScriptはAWS SDK for JavaScriptで実装することになりますね。
Action Scriptが対応しているライブラリは以下で確認できます。
https://auth0-extensions.github.io/canirequire/
AWS SDK for JavaScript v3が対応しているようですね。
また、自動移行に関しても徐々に移行できるので大量のユーザーを移行する場合に便利だと感じました。
大量データを一気にインポート・エクスポートしようとすると時間が掛かるため、移行作業によるメンテナンスを意識する必要があるのと
インポート・エクスポートする際のAuth0ManagementAPIのリクエスト制限に引っかかることがあるので、注意が必要です。