Auth0 Rule でサインアップ処理をフックする

2019.06.21

渡辺です。

サインアップ時は、 ユーザテーブルを初期化 したり、 初回登録時のクーポンを発行 したり、なんらかの処理を行いたいユースケースは多くあります。 しかし、ユーザ認証基盤がシステム内部ではなく、Auth0といった外部サービスを行う場合、サインアップ処理を外部サービスからフックしなければなりません。

Auth0では、Hooksというズバリの機能があるのですが、現状ではβ版であること、外部コネクション(例えばソーシャルログイン)連携を行っている場合に利用できません。 代わりにRulesを使い、サインアップ処理をフックするのが、現時点でのベストプラクティスです。

ユーザのapp_metadata

Auth0のユーザは、 app_metadata という属性を持ちます。 このオブジェクトは任意の値を格納できるので、ここにサインアップ済みかどうかを表すフラグ signedup を持たせる戦略を取ります。

Ruleの実装

Ruleのロジックとしては、app_metadata.signeduptrue であれば何もしない。 存在しない場合は、サインアップ用のAPIをフックするという流れです。

function (user, context, callback) {
  user.app_metadata = user.app_metadata || {};
  console.log('user.app_metadata.signedup', user.app_metadata.signedup);
  if (user.app_metadata.signedup) return callback(null, user, context);
  let request = require('request');
  let body = {
    user_id: user.user_id,
    user_name: user.name,
    email: user.email,
    phone_number: user.phone_number,
    auth0_tenant: context.tenant
  };
  console.log(JSON.stringify(body, null, 2));
  let option = {
        url: 'https://api.example.com/signup',
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify(body)
  };
  request(option, (error, response, body) => {
     user.app_metadata.signedup = true;
     auth0.users.updateAppMetadata(user.user_id, user.app_metadata);    
     return callback(null, user, context);
  });  
}

ポイントとなるのは auth0.users.updateAppMetadata の呼び出しです。 サインアップ用のフックを実行した後に、 app_metadata を更新するためにこの関数を呼び出してください。 2回目以降のRule実行では、 app_metadata.signeduptrue になるため、サインアップ用のフックは実行されません。

まとめ

Auth0のRuleは強力で、様々な条件でのトリガーとなることができます。 ただし、認証トークンを取得するタイミングで実行されるので、注意しましょう。