なつねこメモ

主にプログラミング関連のメモ帳 ♪(✿╹ヮ╹)ノ 書いてあるコードは自己責任でご自由にどうぞ。記事本文の無断転載は禁止です。

Rails アプリで Google アカウントでログインしたい

Ruby on Rails でログインするようなサービスを作るときに、 ID/PW ではなく、
Twitter や Facebook, Google アカウントでログインさせたいことがしばしばあります。

私の場合は、 Google アカウントでログインさせたいので、その処理方法をメモしておきます。


Google でログインする場合には、 Google API をコールする必要があるので、
Google から提供されている gem を導入します。

Gemfile にこれを追加して、

gem 'google-api-client', '0.9.pre3'

んでインストール。

$ bundle install

次に Controller を作成します。
名前は SessionsController とでもしておきます。

$ rails g controller sessions

ここでは、 new でログイン、 destroy でログアウトということにしたいので、
routes.rb を変更します。

get 'login' => 'sessions#new'
delete 'logout' => 'sessions#destroy'

この時、 Google へのアクセスは OAuth 2 で行うため、コールバック用のも用意しておきます。
とりあえず、 oauth2callback という感じで。

get 'oauth2callback'

なお、 Google のアカウントの識別には、Google アカウントの ID をキーとしておきます。

そして、次に client_secret.json を、 Google Developer Console から DL できるので、
好きな場所へと保存しておきます。
保存場所はどこでもいいのですが、個人的には config の中にいれました。

次に、 SessionsController をいじります。 はじめの方に

require 'google/apis/oauth2_v2'
require 'google/api_client/client_secrets'

と追加しておきます。

んで、 login 部分を次のように

client_secrets = Google::APIClient::ClientSecrets.load('config/client_secrets.json')
auth_client = client_secrets.to_authorization
auth_client.update!(scope: ['https://www.googleapis.com/auth/userinfo.profile'])
session[:oauth] = auth_client.to_json
redirect_to auth_client.authorization_uri.to_s

1 行目の部分、 Google::APIClient::ClientSecrets.load には、
RAILS_ROOT からのパスを入れます。
私は上述のとおり、 config に保存したので、 config/client_secrets.json としています。

また、 scope には使用する API の範囲を指定しておきます。
今回取得したいのは Google アカウントの ID のみですので、上記のもので OK となります。

んで、 oauth2callback には

return redirect_to root_path if params[:code].blank?
auth_client = Signet::OAuth2::Client.new(JSON.parse(session[:oauth]))
auth_client.code = params[:code]
oauth2 = Google::Apis::Oauth2V2::Oauth2Service.new
@user = User.from_google(oauth2.get_userinfo_v2(options: {authorization: auth_client}))
@user.save!
session[:user] = @user.id

といったかんじで。
User.from_google では、 該当している ID がなければ、ユーザーを作成、
存在していればそれを返す処理を行っています。

なお、上のスコープで取得できるものは

#<Google::Apis::Oauth2V2::Userinfoplus:0x007f9658f9a420
 @family_name="三日月",
 @given_name="ふゆの",
 @id="****",
 @link="https://plus.google.com/****",
 @locale="ja",
 @name="三日月ふゆの",
 @picture=
  "https://lh5.googleusercontent.com/****/****/****/****/photo.jpg",
 @verified_email=true>

といったものです。
ここの ID だけ使えば OK かと。