frontendmemo

このサイトは、「html、css、js、ruby,ツールなどについて、自分が覚えたこと、またはいつも忘れて調べることを書き溜め、それが結果といて勉強したての初心者の方や自分と同じような技術レベルの人の助けになることを目的とするWebログ」、略してブログです。挨拶→http://frontendmemo.hatenablog.com/entry/2016/06/25/115845

RailsのomniauthでTwitter認証の手順

スポンサードリンク


スポンサードリンク


railsでログイン時にTwitter認証を実装できるのですが、意外とエラーが多発して難しかったです。
記事によってもやり方は違かったのですが、自分が実現できた方法を書いていきます。

Twitter認証のみの新規アプリとして作ります。

※devise install済みの想定

1.gemのインストール

gemfile

gem 'omniauth-twitter'
gem 'omniauth'
gem 'twitter'
bundle install

2.Userモデルの作成

rails g devise User

マイグレーションファイル
db/migrate/20181027055719_devise_create_users.rb

# frozen_string_literal: true

class DeviseCreateUsers < ActiveRecord::Migration
  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.text :name
      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

自分の場合、デフォルトでTrackableがコメントアウトされておりエラーが出ていました。
同じようになっているか確認します。

app/models/user.rb

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable, :omniauthable
         has_many :articles


  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),
        username: auth.info.nickname,
        password: Devise.friendly_token[0, 20]
      )
    end

    user
  end

  private

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

3. omniauth-twitter用カラムの追加

rails g migration add_columns_to_users provider uid username

db/migrate/20181028115704_add_columns_to_users

class AddColumnsToUsers < ActiveRecord::Migration
  def change
    add_column :users, :provider, :string
    add_column :users, :uid, :string
    add_column :users, :username, :string, default: "anonymous"
  end
end
rake db:migrate

4.キーの登録

config/secrets.yml

  user_consumer_key: "コンシューマーキー"
  user_consumer_secret: "コンシューマーシークレット"
  user_access_token: "アクセストークン"
  user_access_token_secret: "アクセストークンシークレット"

5.コールバック用コントロール作成

app/controllers/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?
      flash[:notice] = I18n.t('devise.omniauth_callbacks.success', kind: provider.capitalize)
      sign_in_and_redirect @user, event: :authentication
    else
      session["devise.#{provider}_data"] = request.env['omniauth.auth']
      redirect_to new_user_registration_url
    end
  end
end

6.routeの設定

config/routes.rb

Rails.application.routes.draw do
  devise_for :users, controllers: { omniauth_callbacks: 'users/omniauth_callbacks' }
  get 'users', to: 'users#index'
  get '/user', to: 'users#user'
  post '/user', to: 'users#user'
  root to: 'users#index'
end

7.viewの作成

app/views/users/index.html.erb

<div class="content">
  <h1>INDEX</h1>
  <div class="user">
    <h2>User Name</h2>
    <%= form_for(@user, url:{ action: 'user' }) do |f| %>
      <%= f.submit 'ユーザーをチェック' %>
    <% end %>
  </div>
</div>

app/views/users/user.html.erb

<h1>User List</h1>

<table>
  <tr><th>name</th></tr>
  <td><a href="https://twitter.com/<%= @user.name %>"><%= @user.name %></a></td>
</table>

以上です。