LoginSignup
3
2

More than 5 years have passed since last update.

Auth0をPasswordless認証機構として使う

Last updated at Posted at 2019-01-04

メモ。

ToDo

  • Auth0のユーザAPIやToken inspectionを使わずに、 email_verified でEmailアドレスの取得を済ませたい気持ちがある
  • LockはEmailアドレスの記憶までは面倒を見てくれないっぽい

... 書いておいてアレだけどソーシャルログインで十分だな。。

何ができるの?

Auth0 ( https://auth0.com ) は7000アカウントまで対応した無料プランを持っており、この無料プランには、いわゆるPasswordless認証機構が含まれている。

これを使うことで、アカウントを要求するWebサイトでよくある:

  1. E-mailアドレスを入力させる
  2. ユーザにE-mailが送られてくる
  3. ユーザがE-mail中のリンクをクリックする
  4. サイトにログイン

というフローを無料で実現できる。認証結果はOpenID Connectで言うところのID Tokenで提供されるため、ID TokenをWebアプリケーション側で検証してやる(& 必要に応じて専用のトークンを更に振り出す)必要はある。

Auth0側でやること

  1. Applicationを作る( https://manage.auth0.com/#/applications ) - これにより、Client IDやClient Secretが発行される。
  2. (APIを作る( https://manage.auth0.com/#/apis ) - これにより、OpenID Connectで言うところのaudienceを作成できる。(Auth0上では Identifier と呼ばれる))
  3. Hosted page( https://manage.auth0.com/#/login_page )をPasswordless用に書き換える (重要)
  4. Connection から Passwordlessを有効にする

Auth0のログインページはLock( https://auth0.com/docs/libraries/lock/v11 )によって提供されているが、Passwordless用のものは別物になるため書き換えが必要になる。ポイントは:

  • var lock = new Auth0LockPasswordless(config... のように Auth0LockPasswordless をインスタンシエートする
  • passwordlessMethod: 'link'config に加える

標準のログインページではPasswordlessは選択肢に表われず、Connectionsから有効にするだけでは使えないことになる。

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  <title>Sign In with Auth0</title>
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>
<body>

  <!--[if IE 8]>
  <script src="//cdnjs.cloudflare.com/ajax/libs/ie8/0.2.5/ie8.js"></script>
  <![endif]-->

  <!--[if lte IE 9]>
  <script src="https://cdn.auth0.com/js/base64.js"></script>
  <script src="https://cdn.auth0.com/js/es5-shim.min.js"></script>
  <![endif]-->

  <script src="https://cdn.auth0.com/js/lock/11.11/lock.min.js"></script>
  <script>
    // Decode utf8 characters properly
    var config = JSON.parse(decodeURIComponent(escape(window.atob('@@config@@'))));
    config.extraParams = config.extraParams || {};
    var connection = config.connection;
    var prompt = config.prompt;
    var languageDictionary;
    var language;

    if (config.dict && config.dict.signin && config.dict.signin.title) {
      languageDictionary = { title: config.dict.signin.title };
    } else if (typeof config.dict === 'string') {
      language = config.dict;
    }
    var loginHint = config.extraParams.login_hint;

    // Available Lock configuration options: https://auth0.com/docs/libraries/lock/v11/configuration
    var lock = new Auth0LockPasswordless(config.clientID, config.auth0Domain, {
      auth: {
        redirectUrl: config.callbackURL,
        responseType: (config.internalOptions || {}).response_type ||
          (config.callbackOnLocationHash ? 'token' : 'code'),
        params: config.internalOptions
      },
      /* additional configuration needed for custom domains
      configurationBaseUrl: config.clientConfigurationBaseUrl,
      overrides: {
        __tenant: config.auth0Tenant,
        __token_issuer: 'YOUR_CUSTOM_DOMAIN'
      }, */
      assetsUrl:  config.assetsUrl,
      allowedConnections: connection ? [connection] : null,
      rememberLastLogin: !prompt,
      language: language,
      languageDictionary: languageDictionary,
      theme: {
        //logo:            'YOUR LOGO HERE',
        //primaryColor:    'green'
      },
      prefill: loginHint ? { email: loginHint, username: loginHint } : null,
      closable: false,
      defaultADUsernameFromEmailPrefix: false,
      passwordlessMethod: 'link'
      // uncomment if you want small buttons for social providers
      // socialButtonStyle: 'small'
    });

    lock.show();
  </script>
</body>
</html>

提供されるToken

適当にscope = openid profile としてOAuth2すると、以下のようなTokenが払い出される。

Access Token

{
  "iss": "https://yuni.auth0.com/",
  "sub": "email|5c2e8f08e8fd56b4e565b117",
  "aud": [
    "https://stripe.local",
    "https://yuni.auth0.com/userinfo"
  ],
  "iat": 1546559613,
  "exp": 1546566813,
  "azp": "as6bZ2s623qL3ga6UI1LqxySAPXFwgwq",
  "scope": "openid profile"
}

Access Tokenにはe-mailアドレスそのものは含まれていない。 profile スコープを要求したうえで、ID Tokenを取得する必要がある。

ID Token

{
  "nickname": "mjt",
  "name": "mjt@cltn.org",
  "picture": "https://s.gravatar.com/avatar/5cbf298165e52d62a8e0fc0114ce9d48?s=480&r=pg&d=https%3A%2F%2Fcdn.auth0.com%2Favatars%2Fmj.png",
  "updated_at": "2019-01-03T23:53:31.322Z",
  "iss": "https://yuni.auth0.com/",
  "sub": "email|5c2e8f08e8fd56b4e565b117",
  "aud": "as6bZ2s623qL3ga6UI1LqxySAPXFwgwq",
  "iat": 1546559613,
  "exp": 1546595613,
  "at_hash": "1JMASj-DhLGRRmtNIDPVtg",
  "nonce": "qwerty"
}

name がEmailアドレスに相当する ...って email_verified とかじゃダメなんだろうか。。(TODO)

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2