面倒な認証を丸投げできる「Auth0」へ既存ユーザーをラクに移行する方法

2017/05/31

Ado Kukic

40

Articles in this issue reproduced from SitePoint
Copyright © 2017, All rights reserved. SitePoint Pty Ltd. www.sitepoint.com. Translation copyright © 2017, KADOKAWA ASCII Research Laboratories, Inc. Japanese syndication rights arranged with SitePoint Pty Ltd, Collingwood, Victoria,Australia through Tuttle-Mori Agency, Inc., Tokyo

運用中のWebサービスで使っている認証・ID管理サービスがある日、終わってしまったら……。そんなとき、既存ユーザーをラクに移行できるAuth0の使い方を紹介します。

ユーザーの移行は怖い作業ですが、避けられない場合もあります。開発者にとっては困難で、ユーザーにとっては不便で、ビジネスオーナーにとってはコストがかかります。ユーザーをあるサービスやプラットホームから別のものに移行しなければならない理由はさまざまで、たとえば、現在利用しているアイデンティティプロバイダがサービスを停止することになった、所属する組織が自分たちでユーザーを管理したくないと考えている、プログラミング言語やフレームワークの変更、そのほかにも多くのことが考えられます。

Auth0はシンプルで簡単に利用できる、優れた認証・ID管理プラットホームを開発者に提供しています。Auth0プラットホームの主な特徴は、ユーザーにパスワードの変更をさせることなく、どのような既存のデータソースからでもユーザーをAuth0に移行できることです。

Stormpathは「Stormpath」というサービスとしての認証(Authentication as a Service)を提供する会社でしたが、最近Oktaに買収されました。OktaはStormpathを2017年8月に廃止すると発表しており、Stormpathを利用している開発者はそれまでに新たなソリューションに移行しなければなりません。そこで、この記事ではStormpathからAuth0へ簡単にユーザー移行ができる方法を紹介します。

Auth0を使えばユーザー移行が簡単になる

Auth0のカスタムデータベース接続機能を使うことで、開発者は任意のカスタムデータストアに接続できます。その名前が示すとおり、Auth0の外部に保存されたユーザー認証情報を確認できるようになります。外部のデータストアはMySQLなどのデータベースでも、Stormpathでも、独自に実装したものでも構いません。Auth0のダッシュボードにスクリプトを書けば外部データストアにアクセスできます。またカスタムデータベース接続機能を使えば、カスタムデータベースの認証情報でログインしたユーザーを自動的にAuth0にインポートできるようになります。カスタムデータベース接続機能はスイッチを切り替えるだけで有効にできます。

カスタムデータベース接続機能を実装してStormpathのユーザーをAuth0に移行するには、カスタムデータベース接続をセットアップし、Stormpath APIを使って既存のStormpathアカウントに接続します。ユーザーは初回ログイン時に既存のStormpath認証情報を入力します。正しく認証されればユーザーアカウントが自動的にStormpathからAuth0に移行できます。ユーザーがパスワードを変更するといった面倒な作業をする必要はありません。また、開発者はStormpathからどのデータを取り込むか決められます。ユーザーの次回ログイン時には、Auth0がそのユーザーが移行済みであることを検出し、ユーザーのAuth0アカウントを使って認証します。

Migration diagram

作業を始めるに当たって、最初にAuth0の無料アカウントにサインアップしてください。有効なStormpathアカウントを持っていて、アカウントのユーザーを移行したいと考えているという前提で記事を進めていきますが、Stompathを使っていない場合でもこの記事に沿って作業すれば別のデータストアに接続できます。

ユーザーインポート機能があるカスタムデータベース接続のセットアップ

Auth0のアカウントを作成したら、カスタムデータベース接続をセットアップしていきます。Auth0の管理ダッシュボードにあるDatabase Connections(データベース接続)の項目に移動してください。

Create DB connection

Create DB Connection(データベース接続の作成)ボタンをクリックし、新たなデータベース接続を作成します。接続名は自由に付けられます。すべてデフォルト設定にしておき、Create(作成)ボタンで接続を作成してください。

Configure DB

次に、データベース接続を使ってStormpathアカウントに接続します。作成した接続をクリックしCustom Databate(カスタムデータベース)タブに移動してください。「Use my own database(独自のデータベースを使う)」という名前のスイッチをONにするとDatabase Action Scripts(データベース動作スクリプト)が有効になります。ここにコードを書いて既存のStormpathユーザーデータストアに接続します。

Login(ログイン)とGet User(ユーザーの取得)という2つのスクリプトを書く必要があります。Loginはログイン手続きを代わりに処理し、Get userはユーザーがパスワードを再設定するときのアカウント検索を管理します。

Enable custom DB

カスタムデータベース接続機能の準備ができたら、次はインポート機能を有効にします。カスタムデータベース接続のデフォルト設定では外部データベースを利用した認証はできますが、ユーザーをAuth0にインポートすることはできません。外部プラットホームからAuth0にユーザーを移行したい場合は、単にスイッチを切り替えるだけです。データベース接続のSettings(設定)タブに移動し「Import Users to Auth0(ユーザーをAuth0にインポート)」という名前のスイッチをONにすれば完了です。

Import to Auth0

スクリプトを実装する前に必要な最後のステップが、デフォルトのクライアントに対してこの接続を有効にすることです。データベース接続のClients(クライアント)タブに移動し、スイッチをONにしてクライアントをDefault Connection(デフォルトの接続先)として有効にします。Auth0のアカウントを最初から持っていた場合は、接続名が異なる可能性があります。

Enable connection

Login

Loginスクリプトはユーザーがログインしようとしたときに、Auth0のデータベースにそのユーザーのアカウントがない場合に実行されます。ここでは、入力されたユーザー認証情報をStormpathのユーザーデータストアに渡して、そのユーザーが有効かどうか確かめる機能を実装します。Auth0はMongoDB、MySQL、SQL Serverを始めとするさまざまなデータベース用にテンプレートを用意しているほか、Stormpath用のテンプレートも提供しています。最初はこうしたテンプレートを使うのが一番です。以降は必要に応じてテンプレートをカスタマイズしたり、自分自身で一からコードを書いたりしても良いでしょう。

Database Action ScriptsはWebtaskサンドボックス内で実行するNode.jsスクリプトです。この記事の趣旨はStormpathのユーザーをAuth0に移行することなので、以下のスクリプトはStormpathのREST API用に設定されています。ほかのプロバイダからユーザーを移行する場合は、自分で実装するかほかのテンプレートを使う必要があります。

それでは、実際のLoginスクリプトで動作の仕組みを確認します。StormpathのREST APIを利用してユーザーを認証します。

function login(username, password, callback) {
  // Replace the YOUR-STORMPATH-CLIENT-ID with your Stormpath ID
  var url = 'https://api.stormpath.com/v1/applications/{YOUR-STORMPATH-CLIENT-ID}/loginAttempts';
  // Add your Stormpath API Client ID and Secret
  var apiCredentials = {
    user : 'YOUR-STORMPATH-API-ID',
    password: 'YOUR-STORMPATH-API-SECRET'
  }

  // Stormpath requires the user credentials be passed in as a base64 encoded message
  var credentials = new Buffer(username + ':' + password).toString('base64');

  // Make a POST request to authenticate a user
  request({
    url: url,
    method: 'POST',
    auth: apiCredentials,
    json: {
      type: 'basic',
      // Passing in the base64 encoded credentials
      value: credentials
    }
  }, function (error, response, body) {
    // If response is successful we'll continue
    if (response.statusCode !== 200) return callback();
    // A successful response will return a URL to get the user information
    var accountUrl = body.account.href;

    // Make a second request to get the user info.
    request({
      url: accountUrl,
      auth: apiCredentials,
      json: true
    }, function (errorUserInfo, responseUserInfo, bodyUserInfo) {
      // If we get a successful response, we'll process it
      if (responseUserInfo.statusCode !== 200) return callback();

      // To get the user identifier, we'll strip out the Stormpath API
      var id = bodyUserInfo.href.replace('https://api.stormpath.com/v1/accounts/', '');

      // Finally, we'll set the data we want to store in Auth0 and migrate the user
      return callback(null, {
        user_id : id,
        username: bodyUserInfo.username,
        email: bodyUserInfo.email,
        // We set the users email_verified to true as we assume if they were a valid
        // user in Stormpath, they have already verified their email
        // If this field is not set, the user will get an email asking them to verify
        // their account. You can decide how to handle this for your use case
        email_verified: true
        // Add any additional fields you would like to carry over from Stormpath
      });
    });
  });
}

Get User

Get Userスクリプトはユーザーがパスワードを再設定しようとしたときに、Auth0のデータベースにそのユーザーのアカウントがない場合に実行されます。Get Userスクリプトを使ってStormpathのデータストアに接続し、データストア内にユーザーが存在するか確認します。存在すればユーザーデータをAuth0に送り、ここでAuth0がユーザーを移行し、パスワード再設定メールを送信します。ユーザーが再設定を確認すれば手続きが完了し、以降はユーザーがアプリにアクセスできるようになります。ユーザーのプロフィールがAuth0に保存されるので、以降のログインはAuth0のデータベースを使って認証されます。

ユーザーをStormpath以外から移行する合は、やはり自分でGet Userスクリプトを実装する必要があります。記事ではテンプレートを使ったStormpath用のGet Userスクリプトを示します。

function getByEmail(email, callback) {
  // Replace the YOUR-STORMPATH-CLIENT-ID with your Stormpath ID
  var url = 'https://api.stormpath.com/v1/applications/{YOUR-STORMPATH-CLIENT-ID}/accounts';
  // Add your Stormpath API Client ID and Secret
  var apiCredentials = {
    user : 'YOUR-STORMPATH-API-ID',
    password: 'YOUR-STORMPATH-API-SECRET'
  };

  // Make a GET request to find a user by email
  request({
    url: url,
    method: 'GET',
    auth: apiCredentials,
    qs: { q: email },
    json: true
  }, function (error, response, body) {
    if (response.statusCode !== 200) return callback();

    var user = body.items[0];

    if (!user) return callback();

    var id = user.href.replace('https://api.stormpath.com/v1/accounts/', '');

    return callback(null, {
      user_id: id,
      username: user.username,
      email: user.email,
      email_verified: true
      // Add any additional fields you would like to carry over from Stormpath
    });
  });
}

LoginGet Userスクリプトによって、ユーザー移行のセットアップと準備ができました。ユーザー移行をテストして作ったコードが動くことを確認するために、ユーザーがログインし保護されたリソースをAPI経由でリクエストするという簡単なアプリケーションを構築します。フロントエンドをAngularで、バックエンドをSpringで作成します。

フロントエンドの構築

Angular 2を使ってフロントエンドを作成します。素早く立ち上げるためにAuth0 Angular 2クイックスタートを使います。ソースコードはここにあります。Auth0では各プログラミング言語やフレームワーク用にクイックスタート、SDK、ガイドを一通り揃えており、こちらで全項目を確認できます。

プロジェクトをダウンロードしたら、auth.config.jsファイルを編集してAuth0の認証情報をセットアップします。ファイルを開いて以下のように値を変更してください。

"use strict";
exports.myConfig = {
    // Your Auth0 ClientID.
    clientID: '{AUTH0-CLIENT-ID}',
    // Your Auth0 Domain
    domain: '{YOUR-AUTH0-DOMAIN}.auth0.com'
};

これらの値は両方ともAuth0の管理ダッシュボードにあります。確認するにはダッシュボードのメインメニューにあるClientsリンクをクリックし、サインアップしたときに作成したDefault Clientを選択してください。Auth0のアカウントを最初から持っていた場合は、カスタムデータベースが有効なデータベース接続を持ったクライアントを選択してください。

値を設定したらファイルを保存しnpm installを実行します。必要な依存オブジェクトをすべてインストールしたらnpm startを実行してプロジェクトを起動します。localhost:3000に移動してアプリの動作を確認してください。

App new

Loginボタンをクリックしてアプリケーションにログインしてください。するとAuth0の画面ロックウィジェットが表示され、ユーザーに対しメールアドレスとパスワードの入力を要求します。ユーザーは認証情報としてStormpathのメールアドレスとパスワードを入力し、認証情報が正しければログインできます。Stormpathのユーザーアカウントを持っておらずログインできない場合は、Stormpathのダッシュボードでアカウントを作ってから、作成したStrompathのユーザー認証情報を使ってログインしてください。

Auth0 Lock Widget

ログインはあっという間だったはずです。トランザクションの応答データを見ると、ユーザーやインポートしたほかのデータはStormpath-Users接続から来ていることが分かります。このユーザーがAuth0に移行されたか確認します。Auth0のダッシュボードにあるUsers(ユーザー)の項目に移動するとログインしたユーザーが表示されています。

Migrated users

これは移行に成功したということです。ユーザーはAuth0に移行されました。次にアプリケーションにログインするときは、Stormpathへの外部呼び出しの代わりにAuth0のデータベースにある認証情報をチェックします。以下のワークフローは、これまでの手順をあらためて図示したものです。

Migration workflow diagram

Call Public API(パブリックAPIの呼び出し)とCall Private API(プライベートAPIの呼び出し)という2つのボタンに気づいた人もいるでしょう。次は、これらのリンクをクリックしたときにデータを返す簡単なバックエンドを構築します。

バックエンドの構築

バックエンドとしてシンプルなSpring Bootアプリケーションを作りRESTful APIを公開します。サンプルアプリケーションのコードはここにあります。セットアップに必要なことは認証情報を使ってアプリケーションを更新するだけです。認証情報はsrc/main/resources/ディレクトリのauth0.propertiesというファイルに格納されています。

次のようにファイルを編集します。

auth0.domain: {YOUR-AUTH-DOMAIN}.auth0.com
auth0.issuer: https://{YOUR-AUTH0-DOMAIN}.auth0.com/
auth0.clientId: {YOUR-AUTH0-CLIENT-ID}
auth0.securedRoute: NOT_USED
auth0.base64EncodedSecret: false
auth0.authorityStrategy: ROLES
auth0.defaultAuth0ApiSecurityEnabled: false
auth0.signingAlgorithm: HS256

ファイルの更新後に次のコマンドを実行すると、アプリケーションを構築できます。

mvn spring-boot:run -Drun.arguments="--auth0.secret=YOUR_SECRET_KEY"

アプリケーションの構築に成功すると、localhost:4000からAPIにアクセスできるようになります。今回使うのは、アプリケーションが公開する/public、/secureという2つのルートです。/publicルートは全員がアクセスできます。一方、/secureルートは認証されたユーザーが正しい認証情報を送信した場合のみ正しく応答します。

Public API

バックエンドを起動したら、フロントエンドアプリケーションに戻ってCall Public APICall Private APIのリンクをクリックしてください。パブリックAPIについてはログインしていなくてもアクセスできますが、プライベートAPIについてはログインしていなければルートを呼び出し適切な応答を取得できません。

Private API

また、Angular 2を使って動的なクラスをいくつか追加し、ユーザーがログインしている間はボタンを両方とも緑色に変えてクリックできることを示すようにしました。

App logged in

Auth0をさらに活用する

記事で説明したユーザー移行機能が、役に立つことを願っています。このように少しづつ移行すればエンドユーザーはなにも意識せずに済みます。ユーザーを少しづつ移行させる余裕がない場合は、既存のユーザーデータストアからAuth0へまとめてインポートもできます。さらに、Get Userスクリプトを作成済みなので、パスワードの変更が必要だと伝えるメールをユーザーに一斉送信し、メールにあるリンクをクリックしてAuth0にアカウントを移行させる、といった使い方もできます。

ユーザー移行にまつわる悩みを解決できたところで、Auth0が認証、認可、ユーザー移行のほかにできることを手短に紹介します。Auth0が持つ機能の多くはスイッチを切り替えるだけで有効にできます。複数要素承認(MFA)もそうした機能の1つです。Auth0が社内で開発したMFAソリューション、Guardianを使えばスイッチ一つでMFAを有効にできます。

サードパーティ製のMFAソリューションや独自に開発したソリューションをすでに利用している場合は、引き続き利用できます。Auth0のRulesという拡張プラットホームを使えば認可の流れを制御できます。サードパーティ製MFAの起動やプログレッシブプロファイリングの実施などさまざまなイベントを任意に設定できます。

Auth0では通常のユーザーネームとパスワードによる認証や、グーグル、Facebook、Twitterを始めとする50以上のソーシャルネットワークへのソーシャル接続やActive Directory、SAML、Google Appsなどへのエンタープライズ接続も利用できます。

最後に

開発者は、カスタムデータベース接続とユーザーインポート機能を使って既存のユーザーを簡単な方法でAuth0に移行できます。ユーザーの移行元がStormpathであろうと、そのほかのプロバイダであろうと、必要なのはデータベースに接続するためのスクリプトを2つ実装するだけです。ユーザーを少しずつ移行する場合も、複数要素承認、異常検知を始めとするAuth0のすべての機能を利用できます。

Stormpathのサービス停止というニュースによって対応に迫られている場合や、そのほかの理由でユーザーを手軽に移行したいと考えているなら、Auth0を試してみてください。無料アカウントにサインアップすればすぐに始められます。

(原文:Easily Migrate Your Existing Users to Auth0

[翻訳:薮田佳佑/編集:Livit

Copyright © 2017, Ado Kukic All Rights Reserved.

Ado Kukic

Ado Kukic

Auth0のフルスタック開発者兼テクニカルライターです。プログラミングと教育に情熱を注ぎ、セキュリティや認証などに関する記事や講座、そのほかの教育用コンテンツの作成に取り組んでいます。フロントエンドではAngular 2を好んで使っていますが、バックエンドではNode.jsとGolangの間を行ったり来たりしています。

Loading...