2019年1月31日木曜日

Auth0でLINEログインを行う(メールアドレスの取得も)

#2019/07/20 修正:user profile scriptの中でのid_tokenの扱いが変わったので修正

こんにちは、富士榮です。

Auth0楽しいです。
LINE Loginも楽しいです。

と、言うことでAuth0を使ってLINE Loginを実装してみます。

ちなみに、Auth0の古田さんが以前書いていらっしゃるQiitaを見ればそのままなんですが、メールアドレスが取れない!という課題が解決していないので、そのあたりもカバーしてみます。

古田さんのQiita:Auth0でLINEログインを実装してみた(v2.1対応)
 https://qiita.com/furuth/items/6df4334c3821ffc69d9c

ざっくり解説すると以下のとおり実装します。細かい手順は古田さんのQiitaを見てください。

  1. Auth0のExtensionの「Custom Social Connections」を使う(流石にLINEはビルトインされていない)
  2. LINE側に登録したClientID、ClientSecretをAuth0のExtensionに設定する
  3. Auth0のExtensionは基本的にOAuthなので、ユーザ属性はLINEのProfileエンドポイントから取得する

LINEの場合、この3番が曲者ですね。
以前、紹介したとおり、LINE Loginでメールアドレスを取得できるようにはなりましたが、あくまでid_tokenの中に入っており、Profileエンドポイントからは取得できないんです。

以前のポスト


と、言うことでAuth0のExtensionの中のプロファイル取得スクリプトでなんとかするしかありません。

が、このプロファイル取得スクリプト、先に書いた通り、OAuthな前提なので、access_tokenを基にProfileエンドポイントへアクセスして属性を取得するようなサンプルしかありません。

今回はここでid_tokenをとってきて中からメールアドレスを取り出したいので、以下のようにスクリプトを書き換えます。access_tokenは使いません。
function(accessToken, ctx, cb) {
  var i = jwt.decode(ctx.id_token);
  var p = {
    user_id: i.sub,
    name: i.name,
    picture: i.picture,
    email: i.email
  };
  cb(null, p);
}

2019/07/20修正 直ってしました
ちなみに、LINEが返してくるid_token(JWT)はヘッダにtyp: JWTの記載がないので、node.jsのjsonwebtokenライブラリがうまくjsonオブジェクトに変換をしてくれず、stringで結果が返ってきてしまします。そのため、2行目でJSON.parseをつけてjsonオブジェクトに変換しています。
※Azure ADなどの場合はtyp: JWTがヘッダにあるので、JSON.parseは不要でした。jwt.decodeの第2引数にjson: trueってつけるとうまいことやってくれる、というドキュメントは見たことがあるんですが、今回は上手く動きませんでした
※場合によってjwt.decodeで怒られることがあるみたいなので、その場合は
 var jwt = require('jsonwebtoken');
 を追記してみてください。

Tryボタンで動作確認ができ、ログインするとこんな感じでid_token内の属性が取得できます。

※(追記)スクリーンショットがわかりにくい(メールアドレスはTryでは出てこない)ので、ユーザ・プロファイルの画面を張っておきます。