タグ別アーカイブ: google

時間が立つとGoogle APIのOAuth認証に失敗する

概要

Googleが提供するツール。便利ですよね。
公式ではよくG Suitesと呼ばれているスプレッドシートや、ドキュメントなどなどのことを指します。
アプリケーションからG Suitesを操作するためにはOauth認証を利用するのですが、今回はその際時間が立つと認証時にエラーが出てアプリケーションからの操作ができなくなる問題に遭遇したのでまとめておきます。

エラー詳細

今回のアプリケーションはG Suitesの操作をアプリケーションで実行しています。
挙動としてはまずOAuthクライアントを作成したユーザで 認証を行い、アクセストークンを取得します。
その後アクセストークンを用いてG Suitesの操作を行うようなごくごくシンプルなものです。

当初はアプリケーションが正常に動作するのですが、一定時間が経過した上で再度実行するとG Suitesの操作を行う際にトークンが正常でないエラーが発生するような現象が起こりました。

もう少し細かい実装について述べましょう。
今回はgoogle側で用意してくれているjavaのライブラリを使用しています。
かなりライブラリが充実しているので普通に考えてこれを使わない手はありません。

認証には公式ガイドに沿った典型的な実装だと思います。

GoogleAuthorizationCodeFlow を利用して認証しアクセストークンを取得します。
また認証した情報は FileDataStoreFactory を用いてローカルディスクに保存します。
一度認証した後はセッションを発行して、二度目以降は保存したトークンを用いてアプリケーションの処理を行います。

原因

一定時間が経過すると再度実行できなくなるということから、おそらくトークンが期限切れになった際にトークンのリフレッシュができていないんじゃないかと当たりをつけました。
ちょうどはじめに返却されるアクセストークンの生存期間が1時間でしたので、期限が切れたタイミングで実施するとやはり、エラーが再現することが確認できました。
更に認証時に返却される情報をよくよく確認してみると、リフレッシュトークンが返却されていません。
なのでFileDataStoreにはアクセストークンなどは保存はされているんですが、当然リフレッシュトークンがないのでアクセストークンの期限が切れた瞬間に再発行ができずにエラーとなっているようです。

今回はリフレッシュトークンが空っぽいという点に気づくのに時間がかかりました。
あとはデバッグする際にはアプリケーションを再起動して確認していたので、初回のアクセストークンが切れる前に再度アクセストークンが新しいものに変わるんですよね。なのでエラーが出るまでに時間がかかるので気づきにくかったです。

調べてみますとこちらに情報があり、リフレッシュトークンは初回の認証した時点でしか返却されないそうです。
なんですが approval_promt=force を指定することで毎回認可ダイアログに飛び、それによってリフレッシュトークンが返却されるようになります。

いろいろ試してみたところ、途中から認可ダイアログが表示されなくなるユーザ(この場合リフレッシュトークンが帰ってこなくなります)もいれば、ずっと認可ダイアログが開くユーザもおり、正直なところ何を基準にそうなっているのかわかりませんでした。

参考URLのようにパラメータを指定することで強制的に認証ダイアログを表示するなり、シークレットをリセットするなりするのが対応としては良さそうです。

参考

https://stackoverflow.com/questions/10827920/not-receiving-google-oauth-refresh-token