Auth0にMysqlに保存しているユーザーを一括インポートしてみる

本日7月7日は弊社の創立記念日だよ
2020.07.07

Auth0に認証を移行しようとした場合、 既存のデータベースやサービスからユーザーの認証情報をAuth0に移行する必要があります。 Auth0ではユーザーの移行に

があります。

今回はcreate import users APIを使用する一括インポートを試したいと思います。

事前準備

移行元のデータを作成

すでに稼働しているシステムでは不要ですが、今回はサンプルデータを用意して試します。

テーブルはこんなのを用意.

CREATE TABLE users (
  id int(10) unsigned not null auto_increment,
  name varchar(255) not null,
  email varchar(255) not null,
  hash varchar(255) not null,
  created_time datetime not null default current_timestamp,
  updated_time datetime not null default current_timestamp on update current_timestamp,
  primary key (id)
);

データとして以下を用意。ハッシュアルゴリズムはSHA256を使用しました。

insert into users(name, email, hash)
values
("sample_user_1","sample1@classmethod.net","BEB47E1B660CD2B55FED9DCCB4FC572A250E165F219926B11D6D6D4DA40BCEAF"),
("sample_user_2","sample2@classmethod.net","AAE0C7FADCA1BDDBE92C3BC0B85B9777625B6BA17E7072D41FAF526C65CB76C9"),
("sample_user_3","sample3@classmethod.net","D892F917156C6CFE42B4D8003B0B15EBC160C0619CAB4F4C2B9DD3968EDED0CC")
;

やってみる

Auth0にインポート用のデータベース接続とアプリケーションを用意する

パスワード認証用のデータベースと、それを使ってログインするアプリケーションを作成する必要があります。

Auth0ダッシュボード -> Connections -> Database のページからコネクションを作成します。

Applicationも同様に、 Auth0ダッシュボード -> Applications のページから作成します。

Applicationの作成後、設定画面のConnectionsタブをクリックし、接続したいConnectionのトグルをONにします。

Auth0にインポートするためのファイルを用意する

Auth0にインポートするユーザーデータを含むJSONファイルを作成する必要があります。

一括ユーザーインポートデータベーススキーマと例

インポート元のデータの name, email, hash をAuth0にインポートしたいので、

{
  "name": "sample_user_1",
  "email": "sample1@classmethod.net",
  "email_verified": true,
  "custom_password_hash": {
    "algorithm": "sha256",
      "hash": {
         "value": "BEB47E1B660CD2B55FED9DCCB4FC572A250E165F219926B11D6D6D4DA40BCEAF",
         "encoding": "hex"
      }
  }
},
{
.........................略
}

といったjsonデータを用意します。

custom_password_hashのオブジェクトですが、 サンプルのインポート元のDBにsha256のデータを格納しているので、

  • algorithm: sha256
  • hash.encoding: hexまたはbase64

でなければいけません。

インポートジョブAPIを実行する

curlを使ってAPIを実行してみます。

curl --request POST \
>   --url 'https://< YOUR_DOMAIN >/api/v2/jobs/users-imports'  \
>   --header "authorization: Bearer < MGMT_API_ACCESS_TOKEN >" \
>   --form "users=@<USERS_IMPORT_FILE.json>" \
>   --form "connection_id=< CONNECTION_ID >" \
>   --form "external_id=< EXTERNAL_ID  >" \
>   --form "upsert=false" \
>   --form "send_completion_email=false"
params
users インポートするユーザーの情報が入ったjsonファイルを指定します
connection_id ユーザーがインポートされるconnectionのID
external_id 複数のジョブを関連付けるために使用できるオプションのユーザー定義の文字列
upsert false: メールアドレス、ユーザーID、またはユーザー名が一致する既存のユーザーは失敗します。 true : これらのフィールドのいずれかに一致する既存のユーザーが更新されますが、更新可能な属性のみが含まれます
send_completion_email true: インポートジョブが完了したときに、完了メールをすべてのテナント所有者に送信します。 false:送信しない

実行後、リクエスト成功で以下のような内容が返却されます。

{
 "type":"users_import",
 "status":"pending",
 "connection_id":"con_3F66IUAL2pCWxqVa",
 "external_id":"sample_user_import_1",
 "connection":"misc-study-archives",
 "created_at":"2020-07-07T06:56:05.308Z",
 "id":"job_SbmUbuE4i82PxR4P"
}

インポートジョブのステータスを確認するには、以下のコマンドを実行します。 JOB_IDにリクエスト送信で返ってきた値を指定します。

curl --request GET \
  --url 'https://< YOUR_DOMAIN >/api/v2/jobs/< JOB_ID >' \
  --header 'authorization: Bearer < MGMT_API_ACCESS_TOKEN >' \
  --header 'content-type: application/json'

結果は、

{
  "type":"users_import",
  "status":"completed",
  "connection_id":"con_3F66IUAL2pCWxqVa",
  "external_id":"sample_user_import_1",
  "summary":{"failed":0,"updated":0,"inserted":1,"total":1},
  "connection":"misc-study-archives",
  "created_at":"2020-07-07T06:56:05.308Z",
  "id":"job_SbmUbuE4i82PxR4P"
}

statusは現在のjobの状態で, ["pending", "processing", "completed", "failed"] があります。

summaryにインポートできたユーザー数や失敗したユーザー数、更新したユーザー数が出力されます。

この例ではcompletedとなっていますので、Auth0ダッシュボードでもユーザーが追加されているか確認してみます。

jsonに記述した名前、メールアドレス、インポートジョブで指定したconnectionにユーザーが登録されていますね。

ログイン確認

ユーザー登録はされたので、実際にログインできるか確認してみましょう。 移行前のパスワードと同じものでログインできるはずです。

おまけ

同じDBに違うハッシュアルゴリズムを使ったユーザーをインポートできるのか?

本記事ではsha256でハッシュ化されたパスワードをインポートしましたが、そこに別のハッシュアルゴリズムを使ったパスワードをインポートできるか気になったのでやってみます(bcryptを使用)。

以下のクエリでテーブルにデータを突っ込みました。

insert into users(name, email, hash)
values
("sample_user_4","sample4@classmethod.net","$2a$08$rSClFWZCKQn/c9.Xv8f0zOxgg.Hap2NsBlY7vEocKh6mHvklt1l8m")
;

usersに設定するjsonふぁいるは

{
  "name": "sample_user_4",
  "email": "sample4@classmethod.net",
  "email_verified": true,
  "custom_password_hash": {
    "algorithm": "bcrypt",
      "hash": {
         "value": "$2a$08$rSClFWZCKQn/c9.Xv8f0zOxgg.Hap2NsBlY7vEocKh6mHvklt1l8m",
         "encoding": "utf8"
      }
  }
}

algorithmbcryptを指定します。 注意点として、hash.valueには$2a$$2b$を前につける必要があります。 $2$, $sha1$, $2x$のバージョンはサポートされていませんでした。

ファイルを作成後、先ほどと同じインポートジョブを実行してみます。

結果、

{
  "type":"users_import",
  "status":"pending",
  "connection_id":"con_3F66IUAL2pCWxqVa",
  "external_id":"sample_user_import_1",
  "connection":"misc-study-archives",
  "created_at":"2020-07-07T07:45:01.382Z",
  "id":"job_q1QHat2BnTR1G9O5"
}

のようにリクエストが受け付けられました。

ステータスを確認してみると、completedで成功していました。

{
 "type":"users_import",
 "status":"completed",
 "connection_id":"con_3F66IUAL2pCWxqVa",
 "external_id":"sample_user_import_1",
 "summary":{"failed":0,"updated":0,"inserted":1,"total":1},
 "connection":"misc-study-archives",
 "created_at":"2020-07-07T07:45:01.382Z",
 "id":"job_q1QHat2BnTR1G9O5"}

もちろんダッシュボード上からもユーザーの確認ができました。

ログインも可能です。

ということで同じデータベースに対して別々のハッシュアルゴリズムを使ったパスワードもインポートできて、ログインもできるということがわかりました。 チャンチャン