要件的に、「ユーザーデータを保存はしないけど Google 認証だけはしたい」という条件があって、巷では Devise を使った例しか見つからなかったので記事にしてみます。
環境: Ruby 2.3.1, Rails 4.2.6 / 5.0.1 1
事前準備
Google で client_id, client_secret を発行しておく。また、リダイレクト先の許可設定もしておく。リダイレクト先は /auth/xxxx/callback
の形にしておくと、のちに困らないはず。今回は xxxx
のところを
google_oauth
にして、 /auth/google_oauth/callback
としてみます(*1)
コーディング
Gem 追加
gem "omniauth-google-oauth2"
を Gemfile に追記して、 bundle install をする
ベースとなる Controller の実装
名前はなんでもいいのですが、ここでは LoginedApplicationController というのを用意して、ログイン状態で使う Controller は全てこれを継承するみたいな想定で作ります。
class LoginedApplicationController < ApplicationController
before_action :authenticate
def authenticate
# session がなかったら
# Google に redirect する
# url は、 /auth/google_oauth (Google にリダイレクト先を登録したときの google_oauth 。 *1 参照) にすると、 OmniAuth が飛ばしてくれる
end
end
callback 先となる部分を用意する
名前はなんでもいいのですが、ここでは例として CallbacksController という名前にします (*2)。
メソッド名もなんでもいいのですが、ここでは omniauth_google という名前にしています (*3)。
class CallbacksController < ApplicationController # *2
#
# 当たり前ですが LoginedApplicationController を継承してしまうと無限ループしちゃうので、
# Callback 用メソッドが呼ばれた時には authenticate メソッドが実行されないようにする
#
# この例では親クラスを分けることによってそれを実装している。
# before_action に if 文を噛ませるなどの対応でも OK
def omniauth_google # *3
# session にセットして、アプリケーションの画面に redirect する
end
end
# callback を、さっき作った callback 先メソッドに流せるように書く
# match のあとに書くのは *1、 actionとして書くのは *2 と *3
match "/auth/google_oauth/callback" => "callbacks#omniauth_google", :via => [:get]
omniauth の設定をしておく
Rails.application.config.middleware.use OmniAuth::Builder do
provider :google_oauth2, ENV['FOOBAR_GOOGLE_CLIENT_ID'], ENV['FOOBAR_GOOGLE_CLIENT_SECRET'],
{name: "google_oauth", approval_prompt: ''}
# name には、Google にリダイレクト先として登録したはずのパスの後半部分 (*1)
end
んで、環境変数として FOOBAR_GOOGLE_CLIENT_ID
と FOOBAR_GOOGLE_CLIENT_SECRET
に適切な値を入れる
これでよし
Advanced
ユーザーを取る
上記で説明した authenticate メソッドで
def authenticate
if request.env['omniauth.auth'].present? && request.env['omniauth.auth']["info"].present?
session['google_data'] = request.env['omniauth.auth']["info"]
としておいて
def current_user
authenticate
@current_user ||= session['google_data']
end
Tips / Troubleshooting
CookieOverflowError
Google から返却されたユーザーデータを全部 session に入れると、 CookieOverflowError に遭遇する。外部ストレージを検討するか、 session には必要なものだけを入れる
-
Rails 4 系でこの実装をしたあとにおもむろに Rails のバージョンもあげてみたけど普通に動いてたので、たぶん大丈夫 ↩