TwitterやFacebookに関するOmniAuthの記事はよくみかけるのですが、Googleについてはあまりないようなので、記事にしておきます。恒例の(?)チュートリアル形式でご紹介します。
目次
環境
- Rails 4.1.1
- devise 3.2.4
- omniauth 1.2.1
- omniauth-google-oauth2 0.2.4
セットアップ
まずは必要なgemをインストールします。
📄Gemfile
gem 'devise' gem 'omniauth' gem 'omniauth-google-oauth2'
📄db/migrate/add_omniauth_to_users.rb
$ bundle install $ rails g devise:install $ rails g devise user $ rails g migration add_omniauth_to_users
deviseが作成してくれたUserモデルにOmniAuthに必要なカラムを追加します。
class AddOmniauthToUsers < ActiveRecord::Migration def change add_column :users, :provider, :string add_column :users, :uid, :string add_column :users, :name, :string add_column :users, :token, :string end end
さっそくDBを作成しましょう。
📄app/models/user.rb
$ rake db:migrate
deviseではデフォルでOmniAuthは有効になっていませんので app/models/user.rb
編集します。deviseメソッドの末尾に :omniauthable
の記述を追記するだけです。
class User < ActiveRecord::Base # Include default devise modules. Others available are: # :confirmable, :lockable, and :timeoutable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, :omniauthable end
最後に、deviseの起動時の設定です。config/initializers/devise.rb
に次の記述を追記します。APP_ID、APP_SECRETはまだ取得していないので、とりあえずこの文字列で定義しておきましょう。
📄config/initializers/devise.rb
# ==> OmniAuth # Add a new OmniAuth provider. Check the wiki for more information on setting # up on your models and hooks. # config.omniauth :github, 'APP_ID', 'APP_SECRET', scope: 'user,public_repo' config.omniauth :google_oauth2, 'APP_ID', 'APP_SECRET'
ひとまず、初期設定はこれで完了です。
ログインしてみる
任意のページに以下のリンクを表示してみましょう。
📄任意のview.html.erb
<%= link_to 'Signin with Google', user_omniauth_authorize_path(:google_oauth2) %>
ここまでの設定が正しくできているなら、次のようなリンクが表示されるはずです。
うん、いい感じ。ノリでこのリンクをクリックしてみると・・・
英語が読めない人でもエラーだなと分かる素敵な画面が表示されました。”Invalide_client”らしいです。そりゃそうだ、まだclient_idが”APP_ID”のままなのですから。
ClientIDの取得
OmniAuth認証を利用するには、GoogleにてクライアントIDを取得する必要があります。次のURLにアクセスしてください。
[CREATE PROJECT]というリンクをクリックします。
任意のPROJECT NAME、PROJECT IDを入力します。
しばらく待つと新しいプロジェクトが完成し自動的にプロジェクトのトップページに誘われます。
画面左のメニューから【APIs】を選択し、必要なAPIを選択します。『Contacts API』『Google+ API』の2つをONにしましょう。
続いてCredentialsの画面に行きます。【CREATE NEW CLIENT ID】ボタンをクリックしましょう。
なんだかよく分かんないダイアログが出てきたぞ・・・。APPLICATION TYPEは『Web application』で間違いないですね。しかしあとはよく分かんないので、このまま【Create Client ID】をクリックしてしまいましょう!
Client ID for web applicationというセクションが追加されました。どうやら完成したようですな。次の『Client ID』と『Client Secret』をコピーします。
この値を先程の config/initializers/devise.rb
にペースト・・したいところですが、直接ここに指定してしまうとRAILS_ENV環境毎に切り替えられず不便です。Rails 4.1から使用できる config/secrets.yml
に定義してみましょう。
📄config/secrets.yml
development: secret_key_base: XXXXXXXXXXXXXXXXX google_client_id: 取得した Client ID google_client_secret: 取得した Client Secret
そして config/initializers/devise.rb
を編集します。
📄config/initializers/devise.rb
config.omniauth :google_oauth2, Rails.application.secrets.google_client_id, Rails.application.secrets.google_client_secret
Railsを再起動してから、先程の『Signin with Google』を再度クリックしてみましょう。
チクショー! また怒られた! “redirect_url_mismatch”だそうです。GoogleからリダイレクトするURLを許可してやらねばなりません。再びGoogle Developers Consoleを開き、『Credentials』から【Edit settings】ボタンをクリックします。
下のボックス『AUTHORIZED REDIRECT URI』に、先程エラーの出ていたURL”http://localhost:3000/users/auth/google_oauth2/callback”を入力します。
再びログインにチャレンジすると・・・
やった! ついに成功したか?! しかし・・何この『Project Default Service Account』ってダサい名前? ここは自分のアプリ名に変更しましょう。またまたGoogle Developers Consoleに戻り、左のメニューから『Consent screen』を選択します。
どうやらこの画面でアプリの設定をできるようですね。『PRODUCT NAME』を変更すれば先程の表示が変わるはずです。その他ロゴ画像なんかも指定できるようです。
適当な名前に変更したら再々ログイン。Googleの『許可のリクエストページ』のアプリケーションの名前が変更されていると思います。それでは【承認する】をクリックしてみましょう。
エラーです。しかしこのエラーはRails側のエラーですので、Googleの設定はこれでOKということです。rails側の実装に移りましょう。
Rails側を実装する
まずはルーティングを定義します。devise :users
の箇所を次のように変更します。
📄config/routes.rb
devise_for :users, controllers: { omniauth_callbacks: "users/omniauth_callbacks" }
続いて、コールバックで呼び出されるコントローラーを定義します。app/controllers/users
ディレクトリを作成し、その中にomniauth_callbacks_controller.rb
というコントローラーを作成します。
📄app/controllers/users/omniauth_callbacks_controller.rb
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController def google_oauth2 @user = User.find_for_google_oauth2(request.env["omniauth.auth"]) if @user.persisted? flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => "Google" sign_in_and_redirect @user, :event => :authentication else session["devise.google_data"] = request.env["omniauth.auth"] redirect_to new_user_registration_url end end end
ここで一度、試しにログインしてみましょう。 正しく実装できているなら、次のエラー画面が表示されるはずです。
先程のコールバックから呼び出している User.find_for_google_oauth2
が見つからないというエラーです。まだ実装してないので、当然ですなんですけどね。。。さっそく実装しましょう。
📄app/models/user.rb
class User < ActiveRecord::Base # Include default devise modules. Others available are: # :confirmable, :lockable, and :timeoutable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, :omniauthable def self.find_for_google_oauth2(auth) user = User.where(email: auth.info.email).first unless user user = User.create(name: auth.info.name, provider: auth.provider, uid: auth.uid, email: auth.info.email, token: auth.credentials.token, password: Devise.friendly_token[0, 20]) end user end end
self.find_for_google_oauth2
メソッドを追加しました。Googleから送られてくる認証情報のemailをキーに、データベースを検索します。無ければ新規ユーザーということで、ユーザーを追加してから返すという仕様です。認証情報auth
ってどんな内容なんだよ?って方は、https://github.com/zquestz/omniauth-google-oauth2 にAuthHashのサンプルが掲載されていますのでそちらを確認するとよいでしょう。
さて、今一度ログインしてみると・・・
おおっと! ルートURLにリダイレクトされたぞ。これはもう成功しているとしか思えない。念のため&後学のため、ログイン成功したときにリダイレクトするパスを変更して、その画面にユーザー情報を表示させて確認してみましょう。config/routes.rb
を編集します。
📄config/routes.rb
devise_for :users, controllers: { omniauth_callbacks: "users/omniauth_callbacks" } get "pages/user_info", as: "user_root"
4行目を追記しました。ユーザーのルートURLを定義しています。pages/user_info
は任意のパスで構いません。最後に、viewを作成し、ユーザー情報を表示させてみます。
📄app/views/pages/user_info.html.erb
<p><%= current_user.name %></p> <p><%= current_user.provider %></p> <p><%= current_user.uid %></p> <p><%= current_user.email %></p>
さて、上手く表示できるでしょうか? 最後のログインに向かいましょう!
(注意:実際の画面にモザイクはかかっていません) ビンゴぉぉ! 無事ログインに成功したといえよう!! 少々の設定のみでOmniAuth認証が実現しました。便利な時代になったもんですねえ。
その他細かいことは次の参考URLなりGoogle先生なりで漁ってみてください。それではナイスなRailsライフを!陰ながらお祈りしております。
参考URL
関連する記事
- Python+Spotify APIでアーティストをフォローしてみる
- 【Rails】リロード時に特定の処理を実行する
- Rails + simple_form + Foundation 5 チュートリアル
- Ruby on Rails + Bootstrap3 + simple_form チュートリアル
- simple_formとTwitter bootstrapで作る俺流鉄板Railsアプリ(その1)