omniauth-google-oauth2でハマったメモ

2013-06-14

目的

  • Google AnalyticsをAPI経由で操作したい。
  • そのため、まずはGoogleへOAuth2で認可を頂く必要がある。

今回はOAuthまわりでハマったのでメモ。

やりかた

  • Omniauth で GoogleにOAuth2

omniauth-google-oauth2 というomniauthのGoogle版ストラテジーがあります。 使い方は単純で以下のとおり。

  1. Google API Consoleにプロジェクト登録する
  2. ClientIDとClient Secretをゲット
  3. gemをGemfileに追加
  4. ファイル config/initializers/omniauth.rb を追加しClientID/Secretを入力
  5. config/routes.rb にいろいろ追加
  6. app/controllers/oauth_controller.rb とか作る

前半部分はGoogle公式を読んでください。 後半部分はomniauth-google-oauth2を読むといいです。

で、config/initializers/omniauth.rbの設定項目でヘマをしたんです。

config/initializers/omniauth.rb

で、私はGoogleAnalyticsやりたかったのでscopeを以下のように設定してました。これがまずかった。

#invalid_omniauth.rb
Rails.application.config.middleware.use OmniAuth::Builder do
  provider :google_oauth2, 'your_cliant_id', 'your_client_secret',
    {
      scope: 'https://www.googleapis.com/auth/analytics.readonly'
    }
end

ちなみにファイル名は任意ですよ。

insufficientPermissions ??

{"errors"=>[{"domain"=>"global", "reason"=>"insufficientPermissions", "message"=>"Insufficient Permission"}], "code"=>403, "message"=>"Insufficient Permission"}:
{
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "insufficientPermissions",
    "message": "Insufficient Permission"
   }
  ],
  "code": 403,
  "message": "Insufficient Permission"
 }
}

何かが足らないらしい。

scope デフォ要素が足りない

The userinfo.email and userinfo.profile scopes are used by default. By defining your own scope, you override these defaults. If you need these scopes, don’t forget to add them yourself!

ちゃんとREADMEに書いてあるんですが、これまた見落としてました。 userinfo.emailuserinfo.profileは追加しましょうね。

#valid_omniauth.rb
Rails.application.config.middleware.use OmniAuth::Builder do
  provider :google_oauth2, 'your_cliant_id', 'your_client_secret',
    {
      scope: 'userinfo.email,userinfo.profile,https://www.googleapis.com/auth/analytics.readonly'
    }
end

結論

ちゃんとREADME嫁。

refresh_tokenに関する追記

approval_prompt: Determines whether the user is always re-prompted for consent. It’s set to force by default so a user sees a consent page even if he has previously allowed access a given set of scopes. Set this value to auto so that the user only sees the consent page the first time he authorizes a given set of scopes.

access_type: Defaults to offline, so a refresh token is sent to be used when the user is not present at the browser. Can be set to online.

上記のapproval_promptaccess_typeなんですが、組み合わせ次第でrefresh_tokenが発行されないようです。

approvalprompt: auto + accesstype: offline = no refresh_token

approval_prompt、つまり「アカウント連携するぜ、いいよな?」という画面を出すかどうかという設定項目です。 これをauto、つまり、一回認証したらあとはわざわざ何度も「OK」を押さなくても良い、という設定にする。

次にaccess_type、つまり「実際ブラウザでアプリケーションを開いていない状態でもGoogleアカウントにアクセスできるかどうか」という設定項目です。 これをofflineにするとユーザがアクセスせずとも「裏側」でGoogleへアクセスすることができます。

さて、このapproval_prompt: auto + access_type: offlineという組み合わせを使うとrefresh_tokenが発行されないようです。 まあ確かに「一度認証されたのだから無期限にユーザのあずかり知らぬ所でアクセス可能としろ」というわけなので、そこまでの乱暴ぶりは許さないということでしょうか。

#valid_omniauth.rb
Rails.application.config.middleware.use OmniAuth::Builder do
  provider :google_oauth2, 'your_cliant_id', 'your_client_secret',
    {
      scope: 'userinfo.email,userinfo.profile,https://www.googleapis.com/auth/analytics.readonly'
    }
end

追記

もしかしたら、二段階認証を設定しているユーザも同様にrefresh_tokenをもらえないです、いまのところ。

  • このエントリーをはてなブックマークに追加
comments powered by Disqus

About Me

身近な問題をみつけて、それを解決するためのサービスをつくっている。

SFA(営業支援ソフト)会社のJavaエンジニアだった頃に、新サービス開発の依頼を受けてRubyエンジニアとなる。

P4D デザイナー向けプログラム部デザインビギナーズというデザイン勉強会に参加し、デザインの面白さに触れたりしている。

もっと詳しく