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が以下のように表示されるのでこちらを控えて置いてください。
Lineログインのフロー
ウェブログインの処理に伴うステップは、以下のとおりです。
- 必要なクエリパラメータを使用して、アプリからLINEログインの認可URLにユーザーを誘導します。
- LINEのログインダイアログがブラウザで開き、ユーザーはログインして認証を受けます。LINEプラットフォームでユーザーの資格情報が検証された後、ユーザーはアプリから要求される権限を付与することに合意する必要もあります。
- LINEプラットフォームからアプリに、redirect_uriを介してユーザーをリダイレクトします。このとき、認可コードとstateを含むクエリ文字列もアプリに送信されます。
- アプリは、認可コードを使ってエンドポイントURL https://api.line.me/oauth2/v2.1/tokenにアクセストークンを要求します。
- 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