高木のブログ

【Rails】Twitterログイン機能を実装する

2020/08/22

RailsアプリにTwitterアカウントでログインできる機能を実装したのでメモ
Twitterアカウントでログインができればよかったので最低限の実装しかしていない
deviseを使うほどでもないので、omniauth-twitterだけ使った

バージョン

  • ruby: 2.6.6
  • rails: 6.0.3.2
  • omniauth-twitter: 1.4.0

手順

デベロッパー登録と、アプリの作成をしてAPIキーを取得する

省略

Callback URLに

開発段階では必要ないが、最終的に本番URLも必要

GemfileにTwitterログイン用のGem追加

Gemfile
gem 'omniauth-twitter'

OmniAuthの設定ファイル作成

環境変数のTWITTER_API_CONSUMER_KEYTWITTER_API_CONSUMER_SECRETに取得したAPIキーをセットする

config/initializers/omniauth.rb
Rails.application.config.middleware.use OmniAuth::Builder do
  provider :twitter, ENV['TWITTER_API_CONSUMER_KEY'], ENV['TWITTER_API_CONSUMER_SECRET']
end

usersテーブルとUserモデル作成

idは自動採番ではなくTwitterが発行したユーザーIDにしたいので、オートインクリメントしないようにしている

db/migrate/20200820134413_create_users.rb
class CreateUsers < ActiveRecord::Migration[6.0]
  def change
    create_table :users, id: false do |t|
      t.column :id, 'BIGINT PRIMARY KEY'
      t.string :nickname, null: false
      t.string :name, null: false
      t.string :image, null: false

      t.timestamps
    end
  end
end

ユーザーを保存する処理をモデルに追記

app/models/admin_user.rb
class User < ApplicationRecord
  def self.create_or_update_from_auth(auth)
    find_or_initialize_by(id: auth[:uid]).tap do |user|
      user.update!(
        nickname: auth[:info][:nickname],
        name: auth[:info][:name],
        image: auth[:info][:image],
      )
    end
  end
end

ログイン、ログアウトの処理をするコントローラーを作成

app/controllers/sessions_controller.rb
class SessionsController < ApplicationController
  def create
    user = User.create_or_update_from_auth(request.env['omniauth.auth'])
    session[:user_id] = user.id
    flash[:notice] = 'ログインしました。'
    redirect_to root_path
  end

  def destroy
    reset_session
    flash[:notice] = 'ログアウトしました。'
    redirect_to root_path
  end
end

ヘルパーメソッドを追加

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(session[:user_id])
  end

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

ログイン、ログアウトのリンクを追加する

好きな場所に入れる

app/views/layouts/application.html.erb
...省略...

<% if logged_in? %>
  <%= link_to 'ログアウト', logout_path, class: 'text-white' %>
<% else %>
  <%= link_to 'ログイン', '/auth/twitter', class: 'text-white' %>
<% end %>

...省略...

<% if flash[:notice] %>
  <div class="notice">
    <%= flash[:notice]%>
  </div>
<% end %>

...省略...

ルーティングの設定を追記する

config/routes.rb
Rails.application.routes.draw do
  ...省略...

  get '/auth/:provider/callback', to: 'sessions#create'
  get '/logout', to: 'sessions#destroy'

  ...省略...
end

参考


Pixela