【Ruby on Rails】deviseを使ってtwitterのOmniAuthを実装する方法

こんにちは、nishi_talk(@nishi_talk)です。
今回はdeviseを使ってtwitterのOmniAuthを実装する方法をご紹介します。



以下が設定した環境です。

設定環境・バージョンなど

railsのスタート画面が表示されている状態
Railsのバージョン 5.1.4

Twitterの認証用

まずはTwitterのアプリを作成します。
https://apps.twitter.com/Create New Appの登録をします。
アプリの作成が終わったらSettingsページで以下の項目を設定します。

Application Detailsで以下の設定を行います。
Nameにアプリ名
Descriptionにアプリの説明文
WebsiteにアプリのURL
Callback URLに認証時への利用するURL
Privacy Policy URLにプライバシーポリシーのURL
Terms of Service URL利用規約のURL

「Callback URL」の設定は忘れずに設定します。
(とりあえずhttp://localhost:3000でもなんでも設定しないとエラーがでるっぽい)
「Update Settings」を押して設定を完了します。
次に「Permissions」ページで以下の設定をします。

AccessRead and Writeの項目にチェック。
Additional Permissionsにチェックを入れて、「Update Settings」を押して設定を完了します。
次にrails側の設定をします。

gemを追加

Gemfileにdeviseとomniauthとomniauth-twitterのgemを追加します。

gem 'devise'
gem 'omniauth'
gem 'omniauth-twitter'

bundleを行います。

bundle install



deviseをインストール

deviseの設定をして、ログイン機能を作成。

rails g devise:install

config/initializers/devise.rb

# ==> OmniAuth
# Add a new OmniAuth provider. Check the wiki for more information on setting
# up on your models and hooks.
# config.omniauth :github, 'APP_ID', 'APP_SECRET', scope: 'user,public_repo'
#250行目あたりに以下の内容を記述
config.omniauth :twitter, ENV['TWITTER_CONSUMER_KEY'], ENV['TWITTER_CONSUMER_SECRET'], display: 'popup'

先程記述した[TWITTER_CONSUMER_KEY]と[TWITTER_CONSUMER_SECRET]に環境変数を設定します。
[TWITTER_CONSUMER_KEY]にTwitter APPの「Keys and Access Tokens」ページの「Consumer Key (API Key)」。
[TWITTER_CONSUMER_SECRET]には「Consumer Secret (API Secret)」を記述します。

export TWITTER_CONSUMER_KEY=['取得したAPI key']
export TWITTER_CONSUMER_SECRET=['取得したAPI secret']



deviseメソッドを追加

deviseメソッドにTwitter認証用のメゾットを追加します。
生成されたapp/models/user.rbomniauthableを追加します。

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

userモデル編集

userモデルの編集して、app/model/user.rbを下記を追加します。

class User < ApplicationRecord
・
・
・
  def self.find_for_oauth(auth)
  	user = User.where(uid: auth.uid, provider: auth.provider).first

  	unless user
  		user = User.create(
  			uid:      auth.uid,
  			provider: auth.provider,
  			email:    User.dummy_email(auth),
  			password: Devise.friendly_token[0, 20],
  			image: auth.info.image,
  			name: auth.info.name,
  			nickname: auth.info.nickname,
  			location: auth.info.location
  			)
  	end

  	user
  end

  private

  def self.dummy_email(auth)
  	"#{auth.uid}-#{auth.provider}@example.com"
  end
end

Twitter認証で取得したデータをデータベースに記録します。
メールアドレスは入らないっぽいのでダミーで入るように設定します。



コールバック設定

app/controllers/usersという階層にomniauth_callbacks_controller.rbを作成して以下を記述します。

class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
  def twitter
    callback_from :twitter
  end

  private
  def callback_from(provider)
    provider = provider.to_s

    @user = User.find_for_oauth(request.env['omniauth.auth'])

    if @user.persisted?
      flash[:notice] = I18n.t('devise.omniauth_callbacks.success', kind: provider.capitalize)
      sign_in_and_redirect @user, event: :authentication
    else
      session["devise.#{provider}_data"] = request.env['omniauth.auth']
      redirect_to new_user_registration_url
    end
  end
end



controllerを作成

ログイン用のコントローラーを作成します。

rails g controller home index

生成されたapp/home/index.html.erbを下記の編集します。

<ul>
<%if user_signed_in? %>
<li><%=current_user.email%></li>
<li><%=current_user.name%></li>
<li><%=current_user.nickname%></li>
<li><%=current_user.image%></li>
<li><%=current_user.location%></li>
<li><%= link_to "ログアウト", destroy_user_session_path, method: :delete %></li>
  <%else%>
        <li><%= link_to "ログイン", new_user_session_path %></li>
  <%end%>
</ul>

routeを設定

作成したコントローラーのrouteを設定。
config/routes.rbに以下の記述を追加します。

Rails.application.routes.draw do
root "home#index"
get "home/index"
end

devise_for :users, controllers: {
  omniauth_callbacks: 'users/omniauth_callbacks'
}

これで設定は完了です。



参考にさせていただいてサイト様

Devise+OmniAuthを用いてログインするためのメモ
devise gemを使ってtwitter認証の設定
【開発メモ】RailsアプリにTwitterログイン認証機能を実装する方法