はじめに
ほとんど情報が引っ掛からなかったので、ここに記しておきます。
皆さんもOpenID Connectを使ってGoogleのログイン情報を元に自サービスの認証を行うというようなことはやっているもしくは使用した経験はあるのはないでしょうか。
しかし、Refresh Tokenはサービス側もしくはユーザー自身が削除しない限りはGoogleが保持し続けてしまいます。
ここでは、ユーザーが連携を解除した際に後始末をきちんとしようねという啓蒙のために後始末の仕方について書きます。サービス終了時にはクライアント自体を失効して対応しましょう。
Refresh Tokenを失効させない限りは使えてしまうので、ここはしっかりしておきましょう。
合わせて余計なscopeを付与しないようにとかもあるのですが、話題がそれるので記載しません。
あと聞いた話でエビデンスはない話をして恐縮なのですが、1アカウント辺りで発行されるRefresh Tokenは25個らしいです。上限を超えた際は機能しなくなることがありますので、エラーハンドリングはきちんとしておきましょう。
(Googleの仕様書に上限数の記載はありませんが、機能しなくなる話は書いてあります)
後始末に必要なもの
Refresh Token
最終的にAccess Tokenを使用して後始末をしますので、Refresh Tokenが必要となります。
手元にない場合はユーザーに再度Access Tokenを生成してもらってください。出来ない場合はここでの方法は使えませんので、ユーザーに手動で削除する手順を送ってやってもらうようにしてください。
後始末のやり方
失効用のエンドポイントをコールすればOKです。
Googleは各種エンドポイントをしっかりと公開してくれていますので(使い方はそこではわからないのですが)、エンドポイントを確認する際は以下のURLにアクセスしてみてください。
https://accounts.google.com/.well-known/openid-configuration
失効用のエンドポイントについての使い方はなぜか全然見つかりませんでしたが、Stack Overflowにあったので(URLは下に)、それを元に作らせていただきました。
Rubyだと以下でいけます。Refresh Token -> Access Tokenについては記載しません。
def revoke(access_token)
url = URI.parse('https://oauth2.googleapis.com/revoke')
form = {
token: access_token
}
Net::HTTP.post_form(url, form)
end
後始末をしなかった場合に発生する思ってもみない挙動
Refresh Tokenについては誰かが失効しない限りは永遠と同じものが使用されてしまいます。
そのため、以下の手順が発生した際に思ってもみないことが起きてしまいます。
1. ユーザーがGoogleを経由して情報をアプリケーションへ伝える
2. ユーザーが連携を解除する
3. ユーザーが再度Googleを経由して情報をアプリケーションへ伝える
■期待する動作
手順3にてRefresh Tokenが取得できる
■実際の動作
手順3にてRefresh Tokenが取得できない
初回のみ発行については、Googleの仕様書に記載があるので従うしかありません。
RFC的にそこの記載はないので、実装依存で問題ないようです。ただし、この実装をしているのは今のところGoogleしか知りません(同時にMSも実装しましたが、こちらは毎回もらうことが出来ています)
手動でのやり方
ちなみに手動でも連携は解除できます(Googleに限らずですが、ここではGoogleの情報を記載しておきます)。
やり方は簡単で、以下のURLから該当のアプリケーションを削除すればOKです。
逆にいうとユーザーが失効させてしまっている可能性もあるので、実装の際はその考慮を忘れないようにしましょう。
https://myaccount.google.com/u/1/permissions
終わりに
このようにRefresh Tokenが発行されないケースが今のところGoogleしか知りませんが、失効するエンドポイントが存在する場合はきちんと失効させておいた方が何かの折に面倒がなくて良いと思います。
たまに失効用のエンドポイントが存在しないサービスもあるので油断は出来ませんが、存在するのだけでもやっておきましょう。
参考URL
https://developers.google.com/identity/protocols/oauth2/openid-connect
https://stackoverflow.com/questions/62998100/gmail-api-get-new-access-token-after-revoke