omniauth-google-oauth2でハマったメモ
目的
- Google AnalyticsをAPI経由で操作したい。
- そのため、まずはGoogleへOAuth2で認可を頂く必要がある。
今回はOAuthまわりでハマったのでメモ。
やりかた
- Omniauth で GoogleにOAuth2
omniauth-google-oauth2 というomniauthのGoogle版ストラテジーがあります。 使い方は単純で以下のとおり。
- Google API Consoleにプロジェクト登録する
- ClientIDとClient Secretをゲット
- gemをGemfileに追加
- ファイル config/initializers/omniauth.rb を追加しClientID/Secretを入力
- config/routes.rb にいろいろ追加
- 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
anduserinfo.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.email
とuserinfo.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 toforce
by default so a user sees a consent page even if he has previously allowed access a given set of scopes. Set this value toauto
so that the user only sees the consent page the first time he authorizes a given set of scopes.
access_type
: Defaults tooffline
, so a refresh token is sent to be used when the user is not present at the browser. Can be set toonline
.
上記のapproval_prompt
とaccess_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
をもらえないです、いまのところ。