Edited at

Auth0のAutomatic Migration機能で旧DBからのユーザーデータのマイグレーションを行う


概要

既存の認証システムからAuth0に移行を行う際にはユーザーデータをAuth0側にマイグレーションをする必要があります。Custom Databaseの機能を使えば、旧DBのままでもAuth0が使えますが、一番料金の高いエンタープライズプランしか対応していませんし、旧認証システムのサービス解約を伴う場合にはこれは使えません。

Auth0には、Automatic Migrationという機能があり、これを使うことでユーザデータのマイグレーションを行うことが出来ます。

具体的にはユーザがログインを行うたびに、以下のフローを実施して自動でマイグレーションします。


Auth0の設定


  1. ダッシュボードの「Connections>Database」から移行先のDatabaseを選択します


  1. Custom DatabaseタブよりUse my own databaseを有効化します


旧認証システムへ認証するためのスクリプト

Custom Databaseタブ内にLoginとGet UserというDatabase Action Scriptsを定義する箇所がありますが、ここから旧認証システムへログインしたりユーザデータを取得するためのコードを記述します。

LoginスクリプトはAuth0にログインしようとしているユーザのデータが存在しない場合に呼び出されます。

Get Userスクリプトは、サインアップ時のユーザの存在チェックやパスワードの変更時(用途がよくわかってませんが。。)、Auth0マネジメントAPIのユーザ名やパスワードをアップデートするエンドポイントがリクエストされた時に呼び出されます。

例えば、bcryptでハッシュ化されたパスワードを持つMySQLのユーザDBに対してLoginスクリプトを定義すると以下のようなコードになります。ログインに成功すればcallbackにマイグレーションしたいユーザ情報を返します。ログインに失敗すれば、WrongUsernameOrPasswordErrorを返してログイン画面にエラーを表示させるようにします。


Login.js

// eslint-disable-next-line no-unused-vars

function login(email, password, callback) {
const mysql = require('mysql')
const bcrypt = require('bcrypt')

const connection = mysql.createConnection({
host: configuration.DB_HOST, // eslint-disable-line no-undef
user: configuration.DB_USERNAME, // eslint-disable-line no-undef
password: configuration.DB_PASSWORD, // eslint-disable-line no-undef
database: configuration.DB_DATABASE // eslint-disable-line no-undef
})

connection.connect()

const query =
'SELECT account_storages.id as id, email, password, surname, first_name 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)) // eslint-disable-line no-undef
const user = results[0]

bcrypt.compare(password, user.password, function(error, isValid) {
if (error || !isValid) return callback(error || new WrongUsernameOrPasswordError(email)) // eslint-disable-line no-undef

callback(null, {
user_id: user.id.toString(),
username: user.email.replace(/@.+$/, ''),
email: user.email,
email_verified: true,
name: user.first_name + ' ' + user.surname
})
})
})
}



動作確認


ログイン

移行元のMySQLのユーザDBにはhorike37のアドレスのユーザが存在しています。

Auth0で作ったログイン画面からログインします。

ログイン成功後にAuth0のダッシュボードを確認すると以下のようにユーザがマイグレーションされていることが確認できます。


パスワード忘れ

移行前のユーザに対してパスワード忘れからパスワードの変更を行った際でもこのマイグレーション機能はちゃんと動作します。

まずは再発行用のページからメールアドレスを入力して再設定リンクを送信します。

再設定リンクからパスワードを変更します。

同様に変更したパスワードでログインすると、ちゃんと変更後のパスワードでユーザデータのマイグレーションがお行われます。


まとめ

Automatic Migrationの機能を使えばこのようにシームレスにマイグレーションを行うことが出来ます。

ただし、これはログインをきっかけにマイグレーションを行うため、ログインのないユーザに対してはマイグレーションが行えません。一定期間ログインがなければユーザデータを削除するようにアナウンスをするなどの対応は必要になるでしょう。