【Rails】deviseとomniauthでTwitterログイン機能を作るメモ

既にdeviseで普通のログイン機能は作っている前提のメモ。

Gemのインストール

gem 'devise'
gem 'omniauth-twitter'
$ bundle install

TwitterAPIkeyを入手するためにDeveloperに登録

https://developer.twitter.com/en/apps

初めて利用するときは、とりあえずBuilding tools for Twitter usersなどを選択し、アプリの詳細や使い方などを英語で書き、審査へ。 その後、連携するアプリを登録できるので、各自記載する。

APIの設定

config/initializer/devise.rb

config.omniauth :twitter, 'API key', 'API secret'

API keyは他人に見せてはいけないものなので、環境変数や、.gitignoreを各自設定しておくこと。

user.rbの編集

app/models/user.rb

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,
       )
   end

   user
  end

  private

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

uidやproviderなどはusersテーブルにカラムとして存在する必要があるので、なければ追加する。

privateの記述は、Twitterログイン連携ではメールアドレスの取得は不可能らしいので、ダミーとして設定するためのメソッド。

callbackの編集

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?
      print("persisted true")
      flash[:notice] = I18n.t('devise.omniauth_callbacks.success', kind: provider.capitalize)
      sign_in_and_redirect @user, event: :authentication
    else
      print("persisted false")
      session["devise.#{provider}_data"] = request.env['omniauth.auth']
      redirect_to controller: 'sessions', action: 'new'
    end
  end
end

このファイルがなければ、新規作成して記述する。

routeの編集

config/routes.rb

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

他に

resources :users

を記述している場合、それより上に書くこと。

参考:https://qiita.com/yusaku_/items/d49c7f19feda6dba127a

viewの書き方

<%= link_to 'Twitterでログインする', user_twitter_omniauth_authorize_path %>

みたいな書き方でOK

あとは適当にデザインを配置しておく。