技術備忘録

環境構築によるトラブルの解決方法、知った技術のまとめなどを自分のためにも書き連ねていきます。あわよくば誰かの参考になればと思います。

Rails5系でLineログインを実装する

今回すること

LineログインをRailsで実装します。 今回の環境は、Rails 5.1.4、 ruby 2.4.1p111で行っています。

  • Line Developerへの登録
  • Lineログインのフロー
  • Deviseのインストール
  • Omniauthの設定

Line Developeへの登録

Lineログインを実装するためには, Line Developer へ登録を行わないといけないので登録します。 Lineログインのための公式のドキュメントがあるので登録の方はそちらをご覧ください。 LINEログインを利用するには 登録するとChannel ID、Channel Secretが以下のように表示されるのでこちらを控えて置いてください。

f:id:isoflabon:20180126184020p:plain
LineDeveloperの画像

Lineログインのフロー

ウェブログインの処理に伴うステップは、以下のとおりです。

  1. 必要なクエリパラメータを使用して、アプリからLINEログインの認可URLにユーザーを誘導します。
  2. LINEのログインダイアログがブラウザで開き、ユーザーはログインして認証を受けます。LINEプラットフォームでユーザーの資格情報が検証された後、ユーザーはアプリから要求される権限を付与することに合意する必要もあります。
  3. LINEプラットフォームからアプリに、redirect_uriを介してユーザーをリダイレクトします。このとき、認可コードとstateを含むクエリ文字列もアプリに送信されます。
  4. アプリは、認可コードを使ってエンドポイントURL https://api.line.me/oauth2/v2.1/tokenにアクセストークンを要求します。
  5. LINEプラットフォームがアプリからのリクエストを検証し、アクセストークンをアプリに返します。

(line developerより引用)

上記のフローを満たすようにRails側の処理を実装していきます。

Deviseのインストール

アプリケーションとLineを繋ぐためのプロトコルとしてOmniAuth(オムニオース)認証を使います。このプロトコルを使う前にDeviseをインストールする必要があります。Deviseのインストールに関しては こちらが参考になりました。

Omniauthのインストール

次にOmniAuthのインストールです。Gemfileに以下のコードを追加します。

Gemfile

gem 'omniauth-line'

を追加し次に $ bundle installを実行します。 次にChannel IDとChannel Secretの設定を行います。 この2つを.envファイルに書き込んで設定を行うので.envファイルを作成します。

.env

LINE_KEY=自身のChannel ID
LINE_SECRET=自身のChannel Secret

これで設定としては完了です。あとはこの.envファイルをRailsで使います。このファイルを公開してしまうと悪用されてしまう可能性があるので公にしないようにしてください。 次にdeviseの設定ファイルにlineログインの設定を行います。

initializers/devise.rb

config.omniauth :line, ENV['LINE_KEY'], ENV['LINE_SECRET']

コントローラーの設定

$ rails g controller omniauth_callbacks

でomniauth_callbacks_controllerを作成します。

omniauth_callbacks_controller

class OmniauthCallbacksController < Devise::OmniauthCallbacksController
  def line; ; end
end

ルーティングの設定

routing.rb

devise_for :users, controllers: {
  omniauth_callbacks: "omniauth_callbacks"
}

上記のようにルーティングを設定します。ルーティングは $ rails routesで確認できるので確認すると、

user_line_omniauth_authorize GET|POST /users/auth/line(.:format)                omniauth_callbacks#passthru
user_line_omniauth_callback GET|POST /users/auth/line/callback(.:format)       omniauth_callbacks#line

このような表示がされていればルーティングの完了です。 モデルの変更 DeviseでUserモデルを作成していると思うのでそのままUserモデルを変更を加えてLineログインができるようにしたいと思います。

$ rails generate migration change_column_to_user

マイグレーションファイルを追加します。 マイグレーションファイルに以下を追加します。

add_column :users, :provider, :string
add_column :users, :uid, :string
add_column :users, :name, :string

このように設定したら

$ rails db:migrate

を行うことでDBに設定が反映されます。

Userモデルの変更

user.rb

class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable,:rememberable, :trackable, :validatable, :omniauthable

 has_many :social_profiles, dependent: :destroy
 def social_profile(provider)
   social_profiles.select{ |sp| sp.provider == provider.to_s }.first
 end

 def set_values(omniauth)
  return if provider.to_s != omniauth['provider'].to_s || uid != omniauth['uid']
  credentials = omniauth['credentials']
  info = omniauth['info']

  access_token = credentials['refresh_token']
  access_secret = credentials['secret']
  credentials = credentials.to_json
  name = info['name']
  # self.set_values_by_raw_info(omniauth['extra']['raw_info'])
end

  def set_values_by_raw_info(raw_info)
    self.raw_info = raw_info.to_json
    self.save!
  end
end

コントローラーの変更

class OmniauthCallbacksController < Devise::OmniauthCallbacksController
  def line; basic_action end

  private

 def basic_action
   @omniauth = request.env['omniauth.auth']
   if @omniauth.present?
     @profile = User.where(provider: @omniauth['provider'], uid: @omniauth['uid']).first
     if @profile
       @profile.set_values(@omniauth)
       sign_in(:user, @profile)
     else
       @profile = User.new(provider: @omniauth['provider'], uid: @omniauth['uid'])
       email = @omniauth['info']['email'] ? @omniauth['info']['email'] : "#{@omniauth['uid']}-#{@omniauth['provider']}@example.com"
       @profile = current_user || User.create!(provider: @omniauth['provider'], uid: @omniauth['uid'], email: email, name: @omniauth['info']['name'], password: Devise.friendly_token[0, 20])
       @profile.set_values(@omniauth)
       sign_in(:user, @profile)
       # redirect_to edit_user_path(@profile.user.id) and return
     end
   end
   flash[:notice] = "ログインしました"
   redirect_to root_path
 end


 def fake_email(uid,provider)
    return "#{auth.uid}-#{auth.provider}@example.com"
 end
end

これで設定は完了です! リンクを以下のように設定してあげるとログインができます!

<%= link_to "LINE Login", user_line_omniauth_authorize_path %>

ただLineログインがhttpsでしかダメみたいですので、ローカルの環境は一工夫しないといけません。 macの方はngrokというのがbrewでインストールできるのでこちらを使うとローカルでもhttpsが使えるようになります。 ngrokについては以下のサイトがわかりやすく解説されていました。 ngrokの使い方 これで先ほどのリンクからローカル環境でもログインできるようになっていると思います。

参考にさせて頂いたサイト

ngrokの使い方(windows, mac) - Qiita

[*Rails*] deviseの使い方(rails4版) - Qiita

【Rails4, OmniAuth】世界一丁寧なLINE LOGIN導入講座 - Qiita