LoginSignup
1
3

More than 1 year has passed since last update.

【Rails】deviseとomniauth-twitterでTwitterアカウントを使った認証処理

Last updated at Posted at 2021-12-13

環境

ruby 2.6.7
Rails 5.2.6

手順

TwitterAPIの設定

TwitterAPI登録作業については、こちらを参考に行いました
https://pocco.net/twitter-developer/

Twitter社の審査があって、取得に時間がかかるので注意です。

登録が出来たらDeveloper Portalのページで設定します
https://developer.twitter.com/en/portal/dashboard
登録の際に表示されるAPIキーは後で使います。

アプリの作成から
Settings → Authentication settingsと進んで
Callback URLsを設定します。

http://127.0.0.1/users/auth/twitter/callback
http://localhost:3000/users/auth/twitter/callback
http://(本番環境のURL)/users/auth/twitter/callback

スクリーンショット 2021-08-16 6.18.05.png

Railsへの実装

主にこの記事を参考にさせてもらいましたが、今ではインストールするgemが違っていたりするので、以下が今のやり方となります。

Gemfileに以下を追記します

gem 'omniauth-rails_csrf_protection'
gem 'omniauth-twitter'
gem 'devise'
gem 'dotenv-rails'

インストールします

$ bundle install

deviseをインストールします

$ rails g devise:install

実行するとこういうのが出てきて一見エラーに見えますが、
これでdeviseのインストールは成功しています

===============================================================================

Depending on your application's configuration some manual setup may be required:

  1. Ensure you have defined default url options in your environments files. Here
     is an example of default_url_options appropriate for a development environment
     in config/environments/development.rb:

       config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }

     In production, :host should be set to the actual host of your application.

     * Required for all applications. *

  2. Ensure you have defined root_url to *something* in your config/routes.rb.
     For example:

       root to: "home#index"

     * Not required for API-only Applications *

  3. Ensure you have flash messages in app/views/layouts/application.html.erb.
     For example:

       <p class="notice"><%= notice %></p>
       <p class="alert"><%= alert %></p>

     * Not required for API-only Applications *

  4. You can copy Devise views (for customization) to your app by running:

       rails g devise:views

     * Not required *

===============================================================================

ユーザーのテーブルを作成します

$ rails g devise user

Twitterアカウント情報用のカラムがないので、追加(name, uid, provider)

db/migrate/日時_devise_create_users.rb
class DeviseCreateUsers < ActiveRecord::Migration[5.2]
  def change
    create_table :users do |t|
      ## Database authenticatable
      t.string :email,              null: false, default: ""
      t.string :encrypted_password, null: false, default: ""

      ## Recoverable
      t.string   :reset_password_token
      t.datetime :reset_password_sent_at

      ## Rememberable
      t.datetime :remember_created_at

      ## Trackable
      # t.integer  :sign_in_count, default: 0, null: false
      # t.datetime :current_sign_in_at
      # t.datetime :last_sign_in_at
      # t.string   :current_sign_in_ip
      # t.string   :last_sign_in_ip

      ## Confirmable
      # t.string   :confirmation_token
      # t.datetime :confirmed_at
      # t.datetime :confirmation_sent_at
      # t.string   :unconfirmed_email # Only if using reconfirmable

      ## Lockable
      # t.integer  :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts
      # t.string   :unlock_token # Only if unlock strategy is :email or :both
      # t.datetime :locked_at

      t.string :name #追記
      t.string :uid #追記
      t.string :provider #追記

      t.timestamps null: false
    end

    add_index :users, :email,                unique: true
    add_index :users, :reset_password_token, unique: true
    # add_index :users, :confirmation_token,   unique: true
    # add_index :users, :unlock_token,         unique: true
  end
end

マイグレーション

$ rake db:migrate

コントロールを作成します

$ rails g devise:controllers users

APIキーの設定

.envを作成し、2種類のAPIキーを貼り付けます

TWITTER_ID='ペースト'
TWITTER_APP_SECRET='ペースト'

.envがgitに上がるとまずいので、.gitignoreに以下を追記

/.env
config/initializers/devise.rb
Devise.setup do |config|

(省略)

config.omniauth :twitter, ENV['TWITTER_ID'], ENV['TWITTER_APP_SECRET'] #追記

(省略)

end

user.rb編集

app/models/user.rb
class User < ApplicationRecord
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable, :omniauthable

protected
  def self.find_for_oauth(auth)
    user = User.where(uid: auth.uid, provider: auth.provider).first

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

  private

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

メールアドレスはダミーの値が設定されるようになっています

route.rb編集

routes.rb
Rails.application.routes.draw do
  devise_for :users, controllers: { omniauth_callbacks: 'users/omniauth_callbacks' }
end

omniauth_callbacks_controller.rb編集

app/controllers/users/omniauth_callbacks_controller.rb
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController

  def twitter
    callback_from :twitter
  end

  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
      session[:user_id] = @user.id #追記
    else
      session['devise.#{provider}_data'] = request.env['omniauth.auth']
      redirect_to new_user_registration_url
    end
  end
end

以下のリンクでTwitterログイン処理ができます

<%= link_to 'Twitterログイン', user_twitter_omniauth_authorize_path ,method: :post %>
1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3