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.emailanduserinfo.profilescopes 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 toforceby default so a user sees a consent page even if he has previously allowed access a given set of scopes. Set this value toautoso 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をもらえないです、いまのところ。