作業環境
$ ruby --version ruby 2.1.2p95 (2014-05-08 revision 45877) [x86_64-darwin14.0] $ rails --version Rails 4.1.1
実装手順
必要なgemのインストール
まずはomniauthをgemでインストールします。
gem 'omniauth' gem 'omniauth-facebook' gem 'omniauth-google-oauth2'
$ bundle
initializerの作成
config/initializer/omniauth.rb
を作成します。
Rails.application.config.middleware.use OmniAuth::Builder do provider :facebook, ENV['FB_APP_ID'], ENV['FB_SECRET'] provider :google_oauth2, ENV['GOOGLE_CLIENT_ID'], ENV['GOOGLE_CLIENT_SECRET'], name: :google end
これで、/auth/:provider
で各providerの認証ページにリダイレクトされるようになります。
google_oauth2
でname: :google
を設定しておくと、認証URLやコールバックURLでproviderがgoogle
になるので便利です。
ENVの内容は各SNSでアプリやプロジェクトを作成して入手して書き換えてください。
モデルの作成
認証情報のモデルを作成します。
$ rails g model SocialProfile
migrationはここを参考に作っておけば大丈夫でしょう〜。
class SocialProfile < ActiveRecord::Base belongs_to :member store :other validates_uniqueness_of :uid, scope: :provider def set_values(omniauth) return if provider.to_s != omniauth['provider'].to_s || uid != omniauth['uid'] credentials = omniauth['credentials'] info = omniauth['info'] self.access_token = credentials['token'] self.access_secret = credentials['secret'] self.credentials = credentials.to_json self.name = info['name'] self.nickname = info['nickname'] self.email = info['email'] self.image_url = info['image'] self.description = info['description'].try(:truncate, 255) case provider.to_s when 'google' self.nickname ||= info['email'].sub(/(.+)@gmail.com/, '\1') when 'facebook' self.url = info['urls']['Facebook'] end self.set_values_by_raw_info(omniauth['extra']['raw_info']) end def set_values_by_raw_info(raw_info) case provider.to_s when 'google' self.url = raw_info['link'] when 'facebook' # 特に追加する項目なし end self.raw_info = raw_info.to_json end end
コントローラーの作成
各SNSでの認証のコールバックを受けるコントローラーを作成します。
$ rails g controller sessions
class SessionsController < ApplicationController def callback omniauth = request.env['omniauth.auth'] if omniauth.present? # 認証が成功したときの処理 omniauth = request.env['omniauth.auth'] if omniauth.present? profile = SocialProfile.find_or_initialize_by(provider: omniauth['provider'], uid: omniauth['uid']) profile.set_values(omniauth) # ...(ユーザ登録、ログイン等をしておく) end else # 認証情報がないときの処理 # ...(エラーレンダリングとかしておく) end end def failure # 認証が失敗したときの処理(キャンセルを押された時とか) # ...(エラーレンダリングとかしておく) end end
ルーティングの追加
... get '/auth/:provider/callback' => 'sessions#callback' post '/auth/:provider/callback' => 'sessions#callback' get '/auth/failure' => 'sessions#failure' ...
各providerの認証コールバックURLに/sessions/facebook/callback
や/sessions/google/callback
を設定すればOKです。
リンクの設置
<%= link_to 'Facebook連携', '/auth/facebook' %> <%= link_to 'Google連携', '/auth/google' %>
以上です。omniauthかんたんですね!