Rails4でソーシャルログイン(omniauth-twitter)

参考にするサイト

github.com

github.com

github.com

omniauthとは

OmniAuth is a library that standardizes multi-provider authentication for web applications.
OmniAuth strategies have been created for everything from Facebook to LDAP.
LDAP(Lightweight Directory Access Protocol)

gem追加

gem 'omniauth'
gem 'omniauth-twitter'

※deviseはすでにインストールされている前提です ※まだインストールされていない方はこちら
keiwt.hatenablog.com

$ bundle install --path=vendor/bundle

TwiiterのAPI KeyとAPI Secret取得

割愛

※まだの方はこちら

keiwt.hatenablog.com

config/settings.yml

# common settings for production and test and development env
api:
  twitter:
    key   : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    secret: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

※config/settings.ymlは間違えてもgit管理にしないようにしてください

以下を使用しています
github.com

config/initializers/devise.rb

Devise.setup do |config|
  config.omniauth :twitter, Settings[:api][:twitter][:key], Settings[:api][:twitter][:secret]
  ..........
end

DBの整備

  • モデルの生成
$ rails g model User provider uid name image email password

※列は適宜追加してください

  • インデックスの追加
t.index [:provider, :uid], unique: true, name: 'users_social_account_index'

※db/migrate/YYYYMMDDHHMM_create_users.rb

$ bundle exec rake db:migrate

モデルをominiauthableにする

  • app/models/user.rb
class User < ActiveRecord::Base
  devise :omniauthable, :omniauth_providers => [:twitter]
end

devise用のルートの設定

# route for devise(social login)
devise_for :users, controllers: {
  omniauth_callbacks: "omniauth_callbacks",
  sessions: "sessions"
}

devise用のコントローラーの作成

  • rails g controller 'users/omniauth_callbacks'
class Users::OmniauthCallbacksController < ApplicationController
  def twitter
    # You need to implement the method below in your model (e.g. app/models/user.rb)
    @user = User.from_omniauth(request.env["omniauth.auth"])

    if @user.persisted?
      sign_in_and_redirect @user, :event => :authentication #this will throw if @user is not activated
      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
end
  • rails g controller 'users/sessions'
class Users::SessionsController < ApplicationController
end

app/models/user.rbにメソッド追加

def self.from_omniauth(auth)
  where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
    user.email = auth.info.email
    user.password = Devise.friendly_token[0,20]
    user.name = auth.info.name   # assuming the user model has a name
    user.image = auth.info.image # assuming the user model has an image
  end
end

def self.new_with_session(params, session)
  super.tap do |user|
    if data = session["devise.twitter_data"] && session["devise.twitter_data"]["extra"]["raw_info"]
      user.email = data["email"] if user.email.blank?
    end
  end
end

user_omniauth_authorize_path(provider)にアクセスしてみる

https://oops.com/users/auth/twitter

twitterのアプリケーションページでcallback urlを指定してください
※callback urlの設定がない場合は401 Unauthorizedになります(tokenがnil)

Usersテーブルにデータが入っているかを確認する

$ mysql --pager="less -S" -u root
mysql> select * from development.users;

Controller filters and helpers

  • Devise
Devise will create some helpers to use inside your controllers and views.  
  • Omniauth
After making a model named User omniauthable  
and if devise_for :users was already added to your config/routes.rb,  
Devise will create the following url methods:

user_omniauth_authorize_path(provider)
user_omniauth_callback_path(provider)
  • ログインURLの作成
user_omniauth_authorize_path(:twitter)

※/users/auth/twitterのようなURLを作成してくれます

  • ログイン判定
user_signed_in?
  • ユーザー情報にアクセス
current_user
  • セッション情報
user_session
  • コントローラーでログイン判定を前提にしたい
before_action :authenticate_user!

取得できるデータ

provider
uid

info.nickname
info.name
info.location
info.image
info.description
info.urls.Website
info.urls.Twitter

auth.credentials.token
auth.credentials.secret

auth.extra.access_token.token
auth.extra.access_token.secret

auth.extra.access_token.consumer.key
auth.extra.access_token.consumer.secret
auth.extra.access_token.consumer.options.signature_method
auth.extra.access_token.consumer.options.request_token_path
auth.extra.access_token.consumer.options.authorize_path
auth.extra.access_token.consumer.options.access_token_path
auth.extra.access_token.consumer.options.proxy
auth.extra.access_token.consumer.options.scheme
auth.extra.access_token.consumer.options.http_method
auth.extra.access_token.consumer.options.oauth_version
auth.extra.access_token.consumer.options.site
auth.extra.access_token.consumer.http
auth.extra.access_token.consumer.http_method
auth.extra.access_token.consumer.uri

auth.extra.access_token.params.oauth_token
auth.extra.access_token.params[:oauth_token]
auth.extra.access_token.params.oauth_token_secret
auth.extra.access_token.params[:oauth_token_secret]
auth.extra.access_token.params.user_id
auth.extra.access_token.params[:user_id]
auth.extra.access_token.params.screen_name
auth.extra.access_token.params[:screen_name]
auth.extra.access_token.params.x_auth_expires
auth.extra.access_token.params[:x_auth_expires]

auth.extra.raw_info.id
auth.extra.raw_info.id_str
auth.extra.raw_info.name
auth.extra.raw_info.screen_name
auth.extra.raw_info.location
auth.extra.raw_info.description
auth.extra.raw_info.url
auth.extra.raw_info.entities
auth.extra.raw_info.protected
auth.extra.raw_info.followers_count
auth.extra.raw_info.friends_count
auth.extra.raw_info.listed_count
auth.extra.raw_info.created_at
auth.extra.raw_info.favourites_count
auth.extra.raw_info.utc_offset
auth.extra.raw_info.time_zone
auth.extra.raw_info.geo_enabled
auth.extra.raw_info.verified
auth.extra.raw_info.statuses_count
auth.extra.raw_info.lang
auth.extra.raw_info.contributors_enabled
auth.extra.raw_info.is_translator
auth.extra.raw_info.is_translation_enabled
auth.extra.raw_info.profile_background_color
auth.extra.raw_info.profile_background_image_url
auth.extra.raw_info.profile_background_image_url_https
auth.extra.raw_info.profile_background_tile
auth.extra.raw_info.profile_image_url
auth.extra.raw_info.profile_image_url_https
auth.extra.raw_info.profile_link_color
auth.extra.raw_info.profile_sidebar_border_color
auth.extra.raw_info.profile_sidebar_fill_color
auth.extra.raw_info.profile_text_color
auth.extra.raw_info.profile_use_background_image
auth.extra.raw_info.has_extended_profile
auth.extra.raw_info.default_profile
auth.extra.raw_info.default_profile_image
auth.extra.raw_info.following
auth.extra.raw_info.follow_request_sent
auth.extra.raw_info.notifications