LoginSignup
41

More than 5 years have passed since last update.

Rails5 Twitterログインをdevise+omniauthで実装

Posted at

Twitterログインをdeviseとomniauthで実装する方法を説明します。

環境

Rails 5.2.1

手順

  1. Twitter Developer登録
  2. credentials.yml.encにConsumer API keysを設定
  3. gem追加
  4. deviseの設定
  5. userモデルの設定
  6. callbackの設定
  7. viewの設定
  8. route設定

Twitter Developer登録

Twitter Developer でアプリを登録
ローカルで試すときは callback urlに http://127.0.0.1:3000/users/auth/twitter/callback を指定
Consumer API keysを取得

credentials.yml.encにConsumer API keysを設定

Rails5.2では新規アプリを作成した時にconfig/secrets.ymlが生成されず、代わりにconfig/credentials.yml.encが生成されるようになりました。

このcredentials.yml.encに先ほど取得したConsumer API keysを設定

$ EDITOR="vim" bin/rails credentials:edit
credentials.yml.enc
twitter:
  twitter_api_key: API keyを入力
  twitter_api_secret: API secret keyを入力

# aws:
#   access_key_id: 123
#   secret_access_key: 345

gem追加

Gemfileにdeviseとomniauth-twitterのgemを追加

Gemfile
gem 'devise'
gem 'omniauth-twitter'

bundle installを実行

$ bundle install

deviseの設定

下記のコマンドを実行

$ rails g devise:install
      create  config/initializers/devise.rb
      create  config/locales/devise.en.yml
===============================================================================

Some setup you must do manually if you haven't yet:

  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.

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

       root to: "home#index"

  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>

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

       rails g devise:views

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

ターミナルで言われた通り設定を行う

1. デフォルトURLの指定

config/environments/development.rb
# mailer setting
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }

2. root_urlの指定
routes.rbでrootを指定

次に、devise.rb(260行目くらい)にConsumer API keysを設定

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'
config.omniauth :twitter, Rails.application.credentials.twitter[:twitter_api_key], Rails.application.credentials.twitter[:twitter_api_secret], display: 'popup'

userモデルの設定

userモデルを作成

$ rails g devise User

以下を実行してomniauth-twitter用のカラムを追加

$ rails g migration add_columns_to_users provider uid name nickname image
$ rake db:migrate

user.rbを下記のように編集

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

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

   user
  end

  private

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

callbackの設定

controllers/usersにomniauth_callbacks_controller.rbを作成して以下を記述

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

viewの設定

任意のviewで

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

route設定

config/routes.rbを以下を追加

config/routes.rb
devise_for :users, controllers: {
    omniauth_callbacks: 'users/omniauth_callbacks'
  }

確認

サーバーを起動して確認

$ rails s

後は、devise導入によって使えるようになったヘルパーメソッドを使って自由に実装

参考

Rails5.2から追加された credentials.yml.enc のキホン
[Rails] deviseの使い方(rails5版)
Rails deviseで使えるようになるヘルパーメソッド一覧

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
41