Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

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で使えるようになるヘルパーメソッド一覧

daigou26
主にモバイルアプリ開発をしてます。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした