Google Apps Script内部のリフレッシュトークンは、1週間後も有効か(7日認証切れ問題)
前回は、Google Apps Script(以下GAS)のScriptApp.getOAuthToken()がアクセストークンを更新する仕組みを調べました。内部でリフレッシュトークンが保持されている可能性も考察しています。
Google Apps ScriptのOAuth認証URLとリフレッシュトークン有効期限を調査
通常、GCPのOAuth設定でアプリを「外部(External)」かつ「テスト(Testing)」ステータスで公開すると、リフレッシュトークンは7日間で無効化(失効)されます。
そこで今回は、GASが内部で管理しているリフレッシュトークンも、GCPの仕様と同じく「1週間経過すると無効になり、アクセストークンを取得できなくなる可能性」を検証しました。
結論:GAS管理下のリフレッシュトークンは無効化されない
1週間経過後に改めて検証した結果、リフレッシュトークンは無効化されておらず、正常に新しいアクセストークンを取得できることを確認しました。
これにより、GAS標準のトークン管理メカニズムは、GCPの「テスト」ステータスにおける「リフレッシュトークンの有効期限7日」という制約の影響を受けないことがわかります。GASプラットフォーム側で特別に維持されている可能性もあります。
なぜ、テストモードの7日制限を受けないのか
この挙動について、公式ドキュメントに「GASは例外である」と明記された箇所は見当たりません。
しかし、GCPとGASそれぞれの仕様(および今回の検証結果)を照らし合わせると、以下のような仕組みであると考えられます。
トークン管理の仕組みと仕様
-
一般的なOAuthアプリ:開発者がリフレッシュトークンをDB等に保存・管理する。
- GCPの制約(7日制限)が直接適用される。
-
GAS(ScriptApp):GASの実行基盤(ランタイム)が、ユーザーに代わってトークンを内部管理する。
- Googleの内部システムとしてトークンの維持・更新が行われるため、テストモードの制約を直接受けない。
つまり、ユーザーからは「テスト」状態に見えていても、裏側ではGASというGoogleファーストパーティの特権的な仕組みによって、トークンの有効性が維持されていると考えられます。
出典情報
一般的なOAuthアプリ
The only exception to this behavior is if your app requests a subset of the following: name, email address, and user profile (through the userinfo.email, userinfo.profile, openid scopes or their OpenID Connect equivalents).
For such requests, your users do not need to be in the trusted user list, they will not see a warning message, and their authorizations will not expire after 7 days.
If your app uses Sign in with Google to authenticate users then this exception also applies.
If your app requests any other OAuth scopes, then this exception does not apply.
この動作の唯一の例外は、アプリが以下のサブセット(名前、メールアドレス、ユーザープロフィール)をリクエストする場合です(userinfo.email、userinfo.profile、openid スコープ、またはそれらに相当する OpenID Connect スコープ経由)。
このようなリクエストの場合、ユーザーは信頼できるユーザーリストに登録されている必要はなく、警告メッセージは表示されず、承認は 7 日後に期限切れになることはありません。
アプリがユーザー認証に Google でログインを使用している場合も、この例外が適用されます。
アプリがその他の OAuth スコープをリクエストしている場合、この例外は適用されません。
GAS(ScriptApp)
有効なユーザーの OAuth 2.0 アクセス トークンを取得します。
スクリプトの OAuth スコープが、通常は独自の OAuth フローを必要とする別の Google API(Google Picker など)を承認するのに十分な場合、スクリプトはこのトークンを渡すことで、2 回目の承認プロンプトをバイパスできます。
トークンは一定時間(少なくとも数分)後に期限切れになります。
スクリプトは認証の失敗を処理し、必要に応じてこのメソッドを呼び出して新しいトークンを取得する必要があります。
このメソッドから返されるトークンには、スクリプトが現在必要とするスコープのみが含まれます。
以前に承認されたものの、スクリプトで使用されなくなったスコープは、返されるトークンに含まれません。
スクリプト自体が必要とするもの以外に OAuth スコープが必要な場合は、スクリプトのマニフェスト ファイルで指定できます。
どのようなケースで活用できるか
この仕様は、特に自分専用のツールやミニアプリを作成する際に強力な選択肢となります。
通常、無料のGoogleアカウント(Gmail.com)でOAuthクライアントを作成すると、User Typeは「外部」しか選択できません。正式公開前の「テスト」状態では、リフレッシュトークンが7日ごとに切れて再認証が必要になるという壁にぶつかります。
しかし、GASのScriptApp.getOAuthToken()を利用すれば、この「7日認証切れ問題」を回避しつつ、手軽にGoogle APIを利用した開発が可能になります。

