Blog 開発ブログ

Blog

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

概要

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

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

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

Automatic Migration (1).png

Auth0の設定

  1. ダッシュボードの「Connections>Database」から移行先のDatabaseを選択します
スクリーンショット 2019-08-11 10.19.52.png
  1. Custom DatabaseタブよりUse my own databaseを有効化します
スクリーンショット 2019-08-11 10.21.06.png

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

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

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

スクリーンショット 2019-08-11 10.44.20.png

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

// 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の機能を使えばこのようにシームレスにマイグレーションを行うことが出来ます。
ただし、これはログインをきっかけにマイグレーションを行うため、ログインのないユーザに対してはマイグレーションが行えません。一定期間ログインがなければユーザデータを削除するようにアナウンスをするなどの対応は必要になるでしょう。

Our Partners

サーバーレスで
クラウドの価値を最大限にMaximize the cloud value with serverless

Serverless Operationsはこれまでグローバルの第一線で培ってきたクラウド技術(AWS − アマゾンウェブサービス)の豊富な実績と知見を活かし、お客さまのサーバーレスに関するさまざまな課題を解決します。