Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

Rails4でOmniAuthを使用したFacebookログイン機能を実装する

More than 5 years have passed since last update.

はじめに

以前書いた、Rails4でDeviseを用いたユーザーログイン機能の実装を前提として話を進めます。呼んでいない方は、一度目を通してからの方が理解しやすいかと思います。
今回はOmniAuthを使用してFacebookログインを実装していきます。

※OmniAuthはFacebook以外もサポートしていますので、こちらよりリストを確認してください。

環境

  • CentOS 5.6
  • Ruby 2.1.0
  • Ruby on Rails 4.1.1

使用方法

OmniAuthのインストール

はじめにGemfileに以下を追記し、bundle installを行います。

Gemfile
# add below line
gem 'omniauth-facebook'

Modelカラム追加

deviseで追加したmodelをOmniAuthに対応させるためprovider, uidを追加します。

~ rails g migration AddColumnsToUsers provider uid
~ rake db:migrate

providerの設定

使用するproviderをconfig/initializers/devise.rbに書いていきます。

devies.rb
config.omniauth :facebook, "APP_ID", "APP_SECRET"

※ 他のオプションについては、使用するOmniAuthのREADMEを参考にしてください。

対象Modelへのオプション追加

deviseで使用するModelに対してOmniAuthを使用するためのオプションを追加します。
※以下はUserモデルの場合の例です。

user.rb
devise :omniauthable

ここでサーバーを再起動さてルートを確認すると
* user_omniauth_authorize(:provider)
* user_omniauth_callback(:provider)
の2つが追加されているかと思います。

動作検証

ここまでで一旦動作検証をしてみましょう。
以下をviewに追加し、facebookの認証ページに遷移するか確認を行ってください。

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

認証を許可した後、Unknown actionのエラーがでるはずです。これは、callbackのメソッドを指定していないためです。続いてcallbackに関する処理を書いていきます。

callback処理

ルーティングの設定

callbackの処理を書くにあたり、はじめにルーティングを書いていきます。

route.rb
devise_for :users, :controllers => { :omniauth_callbacks => "users/omniauth_callbacks" }

controllerの作成

callbackを受けるためのcontrollerをapp/controllers/users/omniauth_callbacks_controller.rbで作成します。

omniauth_callbacks_controller.rb
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
end

これにfacebookのコールバックを受けるメソッドを作成します。

omniauth_callbacks_controller.rb
def facebook
    # 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 => "Facebook") if is_navigational_format?
    else
      session["devise.facebook_data"] = request.env["omniauth.auth"]
      redirect_to new_user_registration_url
    end
end

modelの設定

続いてcallbackの際に新規登録なのか通常のログインなのかを判定し、処理を行うメソッドを作成します。

user.rb
def self.from_omniauth(auth)
  where(auth.slice(:provider, :uid)).first_or_create do |user|
    user.email = auth.info.email
    user.password = Devise.friendly_token[0,20]
  end
end

sessionの設定

通常、deviseでは登録、サインアップの処理の際にUser.new_with_sessionメソッドが呼ばれます。今回はこのメソッドをfacebookに対応させるために既存のメソッドをオーバーライドします。

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

これでfacebookログインの実装は完了となります。ブラウザにてfacebookログインのアクションにアクセスし、データベースにデータが保存されているかを確認してください。

参考

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