(Rails) Devise+OmniAuthでfacebook認証

gemのインストール

以下のgemをGemfileに足して、bundle install

# Gemfile

gem 'devise'
gem 'omniauth-facebook'

Deviseの設定

rails g devise:install

config/initializers/devise.rbを全部コメントアウトして次のようにする。

 # config/initializers/devise.rb

Devise.setup do |config|
  require 'devise/orm/active_record'
  if Rails.env.production?
    config.omniauth :facebook, 'APP_ID1', 'APP_SECRET1', :scope=>'email,read_stream'
  else
    config.omniauth :facebook, 'APP_ID2', 'APP_SECRET2', :scope=>'email,read_stream'
  end
  config.sign_out_via = :get
end

APP_IDとAPP_SECRETはhttps://developers.facebook.com/apps/から取得。
通常、productionとdevelopmentで別々のアプリを用意しておくと良い。

その後、Userモデルを作成

rails g devise user
rails g migration AddColumnsToUsers provider:string uid:string name:string

Userモデルの修正

次のようにUserモデルを記述

# app/models/user.rb

class User < ActiveRecord::Base
  devise :omniauthable, :database_authenticatable, :trackable
  attr_accessible :provider, :uid, :name, :email, :password
  
  def self.find_for_facebook_oauth(auth, signed_in_resource=nil)
    user = User.where(:provider => auth.provider, :uid => auth.uid).first
    unless user
      user = User.create(
        name:auth.extra.raw_info.name,
        provider:auth.provider,
        uid:auth.uid,
        email:auth.info.email,
        password:Devise.friendly_token[0,20]
      )
    end
    user
  end
end

ログインページの作成

rails g controller users/sessions new destroy

ログインページを次のようにする。

# app/views/users/sessions/new.html.erb

<%= link_to "Sign in with Facebook", user_omniauth_authorize_path(:facebook) %>

コールバックを処理するアクションの作成

rails g controller users/omniauth_callbacks

次のように変更 Devise::OmniauthCallbacksControllerの派生になってることに注意

# app/controllers/users/omniauth_callbacks_controller.rb
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
  def facebook
    @user = User.find_for_facebook_oauth(request.env["omniauth.auth"], current_user)
    if @user.persisted?
      flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => "Facebook"
      sign_in_and_redirect @user, :event => :authentication
    else
      session["devise.facebook_data"] = request.env["omniauth.auth"]
      redirect_to new_user_registration_url
    end
  end 
end

routes.rbから、OmniAuth以外のルートをブロック

# config/routes.rb

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

補足

開発用のFacebookのアプリはWebsite with Facebook Loginをチェックして、次のようにする。
Basic Facebook Developers

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です