Google Apps ScriptのOAuth認証URLとリフレッシュトークン有効期限を調査

公開日: 更新日:

きっかけ

Gmail関連のアップデートの影響か、最近FileMakerからGmailのSMTPサーバーを使ってメール送信していた環境で、「送信エラーになる」という話題をTwitterなどでよく見かけるようになりました。

対策として、Google Apps Script (GAS) を経由してメールを送信する方法が考えられますが、そこで気になるのが「認証トークンの有効期限」です。もし頻繁に再認証(再同意)が必要になるようでは、自動化の運用に乗せるのが難しくなります。

そこで、GASがバックグラウンドでどのようなOAuth認証URLを発行し、アクセストークンを取得しているのか詳しく調べてみました。

GASの認証URLを確認する

実際にGASのエディタでスクリプトを実行し、初回認証が必要になった際に生成されるURLを取得して解析してみます。

function myFunction() {
  // 認証ダイアログを出すために、明示的にトークンを取得するメソッドを実行
  const token = ScriptApp.getOAuthToken();
  console.log(token);
}
認証フローをトリガーするためのテストコード

スクリプト実行時に表示される認証用URLを確認した結果がこちらです。

GASエディタの実行ログに表示された承認URLとプロンプト
GASのエディタと承認を要求されている画面
Googleアカウントへのアクセスリクエスト画面
OAuth認証のリクエスト許可画面

取得したURL

const url = new URL(`https://accounts.google.com/o/oauth2/auth/oauthchooseaccount?client_id=123456789123-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com&redirect_uri=https%3A%2F%2Fscript.google.com%2Foauthcallback&state=13464014877097984000&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fgmail.send&response_type=none%20gsession&access_type=offline&approval_prompt=force&hl=ja&login_hint=sample%40gmail.com&service=lso&o2v=1&theme=mn&ddm=0&flowName=GeneralOAuthFlow`);
console.log(url);
ログから取得したOAuth認証用URL

URLをパースした結果

取得したURLをNode.jsなどでパース(解析)してみると、以下の構造になっていることがわかります。

URL {
  href: 'https://accounts.google.com/o/oauth2/auth/oauthchooseaccount?client_id=123456789123-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com&redirect_uri=https%3A%2F%2Fscript.google.com%2Foauthcallback&state=13464014877097984000&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fgmail.send&response_type=none%20gsession&access_type=offline&approval_prompt=force&hl=ja&login_hint=sample%40gmail.com&service=lso&o2v=1&theme=mn&ddm=0&flowName=GeneralOAuthFlow',
  origin: 'https://accounts.google.com',
  protocol: 'https:',
  username: '',
  password: '',
  host: 'accounts.google.com',
  hostname: 'accounts.google.com',
  port: '',
  pathname: '/o/oauth2/auth/oauthchooseaccount',
  search: '?client_id=123456789123-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com&redirect_uri=https%3A%2F%2Fscript.google.com%2Foauthcallback&state=13464014877097984000&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fgmail.send&response_type=none%20gsession&access_type=offline&approval_prompt=force&hl=ja&login_hint=sample%40gmail.com&service=lso&o2v=1&theme=mn&ddm=0&flowName=GeneralOAuthFlow',
  searchParams: URLSearchParams {
    'client_id' => '123456789123-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com',
    'redirect_uri' => 'https://script.google.com/oauthcallback',
    'state' => '13464014877097984000',
    'scope' => 'https://www.googleapis.com/auth/gmail.send',
    'response_type' => 'none gsession',
    'access_type' => 'offline',
    'approval_prompt' => 'force',
    'hl' => 'ja',
    'login_hint' => 'sample@gmail.com',
    'service' => 'lso',
    'o2v' => '1',
    'theme' => 'mn',
    'ddm' => '0',
    'flowName' => 'GeneralOAuthFlow' },
  hash: ''
}
URLパラメータの解析結果

パラメータを見ると、access_typeoffline が設定されていることがわかります。

これは、「リフレッシュトークン(更新トークン)」を発行するという指定です。Google内部でこのリフレッシュトークンが管理されており、アクセストークンの期限が切れても、自動的に更新してくれる仕組みになっていると思われます。

リフレッシュトークンの有効期限について

ここで少し懸念点があります。通常、Google Cloud Platform (GCP) で外部アプリとして同意画面を設定し、ステータスが「テスト中」の場合、リフレッシュトークンが7日後に期限切れになるという仕様があるからです。

外部ユーザータイプ用に OAuth 同意画面が構成され、公開ステータスが「テスト中」である Google Cloud Platform プロジェクトには、7 日後に期限切れになる更新トークンが発行されます。
ただし、リクエストされた OAuth スコープが、名前、メールアドレス、ユーザー プロファイル( userinfo.email, userinfo.profile, openid スコープ、または OpenID Connect の同等のもの)のサブセットである場合を除きます。

OAuth 2.0 を使用して Google API にアクセスする | Authorization | Google for Developers
GCPドキュメントの更新トークン有効期限に関する記述
Google Cloud Platform ドキュメント:更新トークンの有効期限について

しかし、今回のGASは、個別のGCPプロジェクトを紐付けず、GAS標準の「デフォルトのCloudプロジェクト」を使用しています。

この場合、テストモード扱いにはならず、7日後になっても期限が切れないというのが一般的な理解です。もしこれが切れてしまうと、世界中のGASのトリガー実行が毎週止まってしまうことになるためです。

おそらく期限切れは発生しないと考えていますが、確実な検証のため、7日後に再度スクリプトを実行して確認してみたいと思います。

小巻旭洋のプロフィール写真

小巻 旭洋

2014年からフリーランスとして活動し、2016年に株式会社フルーデンスを設立する。FileMaker開発歴は約10年。多数の企業システム構築を手がけ、特にデータベース設計と、JavaScript連携、Web連携、パフォーマンス最適化を専門としています。2025年から、Web業務システム・アプリ開発をメインに開発をしています。