Tatehitoの技術メモ

ソフトウェアエンジニアです。いろいろ書きます。

【Rails】『omniauth-twitter』でログイン機能を実装する手順

いちいち思い出すのが面倒なので手順を記録しておく。なお『devise』と連携して実装する場合はこの通りでは無い。

確認環境

  • Rails 6.0.0
  • Ruby 2.6.3
  • omniauth 1.9.0
  • omniauth-twitter 1.4.0

1.TwitterAPIの登録

developer.twitter.com

CallBack_URLの設定に注意。適切に設定しないとエラーになる。ローカル環境で開発する場合はとりあえず以下にしておけばOK。(ポート番号は環境に合わせて。)

http://127.0.0.1:3000/auth/twitter/callback
http://localhost:3000/auth/twitter/callback

2.Gemのインストール

以下の3つのgemをインストール。bundle installを忘れずに。

# Gemfile

gem 'omniauth'
gem 'omniauth-twitter'
gem 'dotenv-rails'

3.APIキーの登録

.envにAPIキーを設定する。いわずもがな、.envはgit管理対象から外しておく。

# .env

TWITTER_KEY='<KEY>'
TWITTER_SECRET='<SECRET>'

ommiauthにもキーを設定する。config/initializers/omniauth.rbを作成し以下のように記述。

# config/initializers/omniauth.rb

Rails.application.config.middleware.use OmniAuth::Builder do
  provider :twitter, ENV["TWITTER_KEY"], ENV["TWITTER_SECRET"]

  OmniAuth.config.on_failure = Proc.new { |env|
    OmniAuth::FailureEndpoint.new(env).redirect_to_failure
  }
end

4.Userモデル作成

Userモデルを作成し、取得した情報をセットするクラスメソッドを定義する。

取得できる情報はこちらに記載があるので、必要に応じて取得するようにする。

rails db:migrateを忘れずに実行する。

rails g model user provider:string uid:string user_name:string screen_name:string image_url:string
# マイグレーションファイル

class CreateUsers < ActiveRecord::Migration[6.0]
  def change
    create_table :users do |t|
      t.string :provider
      t.string :uid
      t.string :user_name
      t.string :screen_name
      t.string :image_url

      t.timestamps
    end
  end
end
# app/model/user.rb

class User < ApplicationRecord
  def self.find_or_create_from_auth(auth)
    provider = auth[:provider]
    screen_name = auth[:extra][:raw_info][:screen_name]
    uid = auth[:uid]
    user_name = auth[:info][:name]
    image_url = auth[:info][:image].gsub(/_normal.jpg/, ".jpg")

    self.find_or_create_by(provider: provider, uid: uid) do |user|
        user.user_name = user_name
        user.image_url = image_url
        user.screen_name = screen_name
    end
  end
end

5.Sessionコントローラー作成

ログイン・ログアウトを行うコントローラーを作成する。合わせてルーティングも定義する。

# app/controllers/session_controller.rb

class SessionsController < ApplicationController
  def create
    user = User.find_or_create_from_auth(request.env['omniauth.auth'])
    session[:user_id] = user.uid
    redirect_to root_path
  end

  def destroy
      reset_session
      redirect_to root_path
  end

  def failure
    redirect_to root_url
  end
end
# config/route.rb

Rails.application.routes.draw do
  get '/auth/:provider/callback', to: 'sessions#create'
  get '/auth/failure', to: 'sessions#failure'
  get '/signout', to: 'sessions#destroy'
end

6.ヘルパーメソッドを定義

ログイン中のユーザー情報の取得および、ログイン中か確認するヘルパーメソッドをapplication_controller.rb定義し各所で呼び出せるようにしておく。

# app/controllers/application_controller.rb

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
    helper_method :current_user, :logged_in?

    private

    def current_user
      return unless session[:user_id]
      @current_user ||= User.find_by(uid: session[:user_id])
    end

    def logged_in?
      !!session[:user_id]
    end
end

7.動作確認

以上で準備完了。get '/auth/twitter'でログイン、get '/signout'でログアウトできる。

erbで書くならこんな感じ。

<% if logged_in? %>
  <%= link_to 'Logout', '/signout' %>
<% else %>
  <%= link_to 'Twitter Login', '/auth/twitter' %>
<% end %>

もし403エラーが出る場合、TwiiterAPIのCallback_URL設定がおかしい可能性が高いので、再度確認する。