【Rails】LINEログインでemailを取得する

こんにちは！本日はLINEログイン時にemailを取得する方法をお伝えします！
facebookは取得できるのに、LINEはgemのデフォルトで取ってこれていないようでした。
そこで必要な部分をオーバーライドして使います！

(【注意】本記事は[omniauth-line](https://github.com/kazasiki/omniauth-line)のプラグインを利用しています)


## 【目次】
1. `LINE delvelopers`でemail取得申請をする
2. omniauth-lineをオーバーライドして`id_token`のペイロードからemailを取得する



# 1.LINE delvelopersでemail取得申請をする

LINE側にLINEログインの時にemail情報遣わせてもらえるように申請します。
(その際に、ユーザーに許可を求めている文言等の確認を送る、そして待つ(1日くらい？))

↓こちらに関しては公式ドキュメント・他の方々の記事が参考になります。↓
[メールアドレス取得権限を申請する(公式)](https://developers.line.biz/ja/docs/line-login/web/integrate-line-login/)
[RailsでOpenID connectを用いたLINEログイン](https://qiita.com/yukibaragi/items/df810e77d1029ac838ad)


## 2.omniauth-lineをオーバーライドして`id_token`からemailを取得する

ここからが出番です！

【結論】以下のように`omniauth-line`gemの[omniauth/strategies/line.rb](https://github.com/kazasiki/omniauth-line/blob/master/lib/omniauth/strategies/line.rb)オーバーライドするだけです。

```ruby
# app/config/initializers/omniauth/strategies/line.rb

require 'omniauth-oauth2'

module OmniAuth
  module Strategies
    class Line < OmniAuth::Strategies::OAuth2
      option :scope, 'email profile openid'　#追記

      info do
        {
          name:        raw_info['displayName'],
          image:       raw_info['pictureUrl'],
          description: raw_info['statusMessage'],
          email:    JWT.decode(access_token.params['id_token'], ENV['LINE_CHANNEL_SECRET']).first['email'] #追記
        }
      end
    end
  end
end

```
`option :scope`→ユーザーが付与する権限
`option :scope`で`email`を追加
(ユーザーが付与する権限に`email`もどうぞ使ってください！といった感じですね。)


実際に確認して見ます(以下の情報は加工してあります)。

```ruby

# access_token.params['id_token']

<OmniAuth::AuthHash 
credentials=
  #<OmniAuth::AuthHash 
    expires=true 
    expires_at=1566893036 
    refresh_token="sAuxKnUCETKgOYs2ll7J" 
    token="eyJhbGciOiJIUzI1NiJ9.Hj3glrwEWDOPWZNnTLjqsdy2l78TgLlZYVX3AurU6dPhenV4u_G5sZ_aqVWfwmVWcvYlF_Rhf-    6D_BoRqMY66lMAa0sb63mvsma1d_av1JZgl8TrpN9WLi4p7UfWxv3QvM8lEQn0qZrQeU3Vp88Kv097jRKgdC7Z364TgZZD6OU.CEouR6pTTLEHp..."> 
    extra=#<OmniAuth::AuthHash> 
    info=#<OmniAuth::AuthHash::InfoHash description=nil 
    email="eyJ0eXAiOiJKV1QiLCJhbGciOdcdscsdciJIUzI1NiJ9.eyJpc3MiOiJodHRwczovL2FjY2Vzcy5saW5lLm1lIiwic3ViIjoiVTNlcdcsNGJkNjYyOTU4NjIzMTVkYmRmODVmNGMxMDY1M2Y2IiwiYXVkIjoiMTYxNjIyOTMxNCIsImV4cCI6M..." 
    image="https://profile.line-scdn.net/0hk1oz7EfkNB5cdc...
    name="example"> 
provider="line" 
uid="U3e4bd6629586..."
>

```

`OmniAuth::AuthHash`(id_tokenのペイロード)にemail情報が含まれていますね！
しかし、現状だとわからないのでJWTでデコードします。

`ENV['LINE_CHANNEL_SECRET']`はLINEの`Channel Secret`のことです。

```ruby
JWT.decode(access_token.params['id_token'], ENV['LINE_CHANNEL_SECRET'])
```

すると以下のように

```ruby
<OmniAuth::AuthHash 
  credentials=#<OmniAuth::AuthHash 
  expires=true 
  expires_at=1566894068 
  refresh_token="UvrpsvdMgwNYHLC4LO9j" 
  token="eyJhbGciOiJIUzI1NiJ9.Cl3zWMKrL6g59qIbWWk0nhdfhNLFB7NNZiSIoHI8zKq89BW77wIx-jregc-jxfENUYwTjZkNwK0lYlz7c4ZRTOcF2iWJK3zl1aTKroyF9lfNj1aThmBeyVioNvbbfSIjLmdpK2jjBh1E2j59D_twbHWTFWiAwuI7qokOp_z8lbI.G8QUoudL46KbuyqhN7UpvBa1PenH6MDQvNPrD_tGz-8"> 
  extra=#<OmniAuth::AuthHash> 
  info=#<OmniAuth::AuthHash::InfoHash 
  description=nil 
  email=[#<OmniAuth::AuthHash amr=#<Hashie::Array ["linesso"]> aud="1616229314" 
  # emailが認識できるようになる！
  email="example@gmail.com" 
  exp=1564305669 
  iat=1564302069 
  ・
  ・
  ・
```

email情報が認識できる形になりましたね！
[JSON Web Tokens - jwt.io](https://jwt.io/)でもペイロードさえ入力すればデコードしてくれるのでJWTが何をしているかよくわからない方はおすすめです。

これでemailの取得は完了です。`request.env['omniauth.auth']`からでもemailからでも取得できるので
formの`value`に入れて初期値っぽくしてしまいましょう！

```ruby
p request.env['omniauth.auth'][email]

> example@gmail.com
```