読者です 読者をやめる 読者になる 読者になる

おれんじりりぃぶろぐ

きっと何者にもなれないエンジニアのブログ

deviseでTwitterアカウントを使ってログイン機能を実装してみた

外部アカウント(今回はTwitter)を使ってのログイン機能の実装をしてみた時のメモ。

Twitter APPを作成する

まずTwitter DeveloperでAPPの作成を行う。
APP作成には電話番号登録が必須になったみたい(´;ω;`)

railsプロジェクトを用意する

rails new devise_twitter_test
cd devise_twitter_test

gemfileに以下を追記して、bundle installを行う。

# Use devise as login system
gem 'devise'
# Use omniauth as Twitter etc... login
gem 'omniauth-twitter'
bundle install

続いて、Userモデルを作成する。

rails g model User provider uid name

さらにコントローラーを作成し、ルーティングルートを設定しておく。

rails g controller Home index

OmniAuthを使う

デバイスの設定を行う。

rails g devise:install

config/initializers/devise.rbに以下を設定する。

config.omniauth :twitter, 'APP_ID', 'APP_SECRET', display: 'popup'

次にUserモデルを作成する。

rails g model User provider uid name

app/models/user.rbを以下のように変更する。

class User < ActiveRecord::Base
  devise :omniauthable
end

さらにconfig/routes.rbを以下のようにする。

Rails.application.routes.draw do

  root "home#index"
  get "home/index"

  devise_for :users, :controllers => { :omniauth_callbacks => "users/omniauth_callbacks" }
  devise_scope :user do
    get 'sign_out', :to => 'devise/sessions#destroy', :as => :destroy_user_session
  end
end

上記の設定を行うと以下のようなルーティングが自動的に生成される。

user_omniauth_authorize GET|POST /users/auth/:provider(.:format)        devise/omniauth_callbacks#passthru {:provider=>/twitter/}
user_omniauth_callback GET|POST /users/auth/:action/callback(.:format) devise/omniauth_callbacks#(?-mix:twitter)

Controllerを作成する

app/controller直下にuserディレクトリを作成しその中にomniauth_callbacks_controller.rbを作成する。

class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
  def twitter
    @user = User.find_or_initialize_by(user_params) # 見つからない場合は新規作成

    if @user.new_record? # 新規作成の場合実行される
      @user.name = request.env["omniauth.auth"].info.nickname
      @user.save
    end

    if @user.persisted? #DBに保存済みかどうか
      sign_in_and_redirect @user, :event => :authentication
      set_flash_message(:notice, :success, :kind => "Twitter") if is_navigational_format?
    else
      session["devise.twitter_data"] = request.env["omniauth.auth"]
      redirect_to new_user_registration_url
    end
  end

  private
  def user_params
    request.env["omniauth.auth"].slice(:provider, :uid).to_h
  end
end

Viewを作成する

app/views/layouts/application.html.erb中にTwitterログイン/ログアウトへのリンクを張る。

<% if user_signed_in? %>
      <%= link_to "Sign out", destroy_user_session_path %>
<% else %>
      <%= link_to "Sign in with Twitter", user_omniauth_authorize_path(:twitter) %>
<% end %>

<% if !current_user.nil? %>
    <p>ようこそ<%= current_user.name %></p>
<% end %>

f:id:orange_lily27:20150720195947p:plain

コントローラーでは@user.name = request.env["omniauth.auth"].info.nicknametwitterのIDを取得した。その他の値については以下を参照。

参考