AWS Cognitoの「Refresh Token has expired」を修正し、不規則なログアウトを停止する

intermediate☁️ AWS2026-06-05| AWS Cognito User Pools, AWS SDK, AWS Amplify

Error Message

NotAuthorizedException: Refresh Token has expired
#aws#cognito#security#authentication#javascript

突然消えるセッションの謎ユーザーがブラウジング中に突然ログイン画面に戻されてしまうことがあります。チェックアウトの途中だったか、複雑なフォームの入力中だったかは関係ありません。セッションが単に消えてしまったのです。ログを調査すると、原因が見つかります:NotAuthorizedException: Refresh Token has expired。これはクラッシュではなく、設定された制限時間がついに訪れたことを意味します。

これは、60分間有効なidTokensをサイレントに取得するために使用される長期的な認証資格情報であるrefreshTokenがついに期限切れになったときに発生します。トークンが制限(24時間や30日など)に達すると、Cognitoは新しい資格情報の発行を拒否します。バックグラウンドでのリフレッシュ処理が失敗し、ユーザーは最初からログインし直すしかなくなります。

なぜ今これが発生しているのか?Cognitoが壊れているわけではありません。アプリクライアントの設定通りに動作しているだけです。おそらく以下の3つのシナリオのいずれかに該当します:

  • 制限的なデフォルト設定: アプリクライアントで設定されている有効期限(デフォルトの1日など)が短く、ユーザーの行動パターンに合っていない。- 単位のミス: 30日間に設定するつもりが、誤って30時間に設定してしまった。- ゾンビ状態: フロントエンドが、トークンの健全性を事前に確認せず、APIコールが失敗するまでセッションが有効であると想定している。## 解決策:セッション期間の延長RefreshTokenValidity(リフレッシュトークンの有効期間)を調整することで、この問題をすぐに解決できます。現代的なウェブアプリケーションの多くは、摩擦のない体験を提供するために、少なくとも30日間を目指しています。

オプション1:AWSコンソール(手動修正)- Cognitoコンソールを開き、ユーザープールを選択します。- アプリケーションの統合タブに移動し、下部のアプリケーションクライアントまでスクロールします。- フロントエンドで使用している特定のクライアントをクリックします。- トークンの有効期限を見つけ、編集をクリックします。- リフレッシュトークンの有効期限の値を変更します。Cognitoでは60分から3,650日(10年)まで設定可能です。- 変更を保存します。これにより、新しいログインからこの長い有効期限が適用されます。### オプション2:AWS CLI(DevSecOps向け)複数の環境を管理している場合は、UIをクリックして回る必要はありません。このコマンドを使用して90日間の有効期限を設定し、「一度設定すればOK」の状態にしましょう:

aws cognito-idp update-user-pool-client \
  --user-pool-id us-east-1_exampleID \
  --client-id your_client_id \
  --refresh-token-validity 90 \
  --token-validity-units "{\"RefreshToken\":\"days\"}"

オプション3:防御的なコードの実装設定の変更は 新しい セッションにのみ適用されます。既存の期限切れトークンを適切に処理する必要があります。アプリをクラッシュさせるのではなく、例外をキャッチしてユーザーを適切にリダイレクトしましょう。

import { Auth } from 'aws-amplify';

async function checkSession() {
  try {
    return await Auth.currentSession();
  } catch (err) {
    if (err.code === 'NotAuthorizedException') {
      // 期限切れのリフレッシュトークンを処理するクリーンな方法です
      console.error("セッションが期限切れです。ローカルキャッシュをクリアしています...");
      await Auth.signOut();
      window.location.href = '/login?reason=expired';
    }
  }
}

30日待たずに修正を検証する修正が機能したかどうかを確認するために1ヶ月待つ必要はありません。5分で検証可能です:

  • 一時的なテスト用アプリクライアントを作成します。- リフレッシュトークンの有効期限を1時間(最小値)に設定します。- ログイン後、手動でシステムクロックを進めるか、単に61分待ちます。- トークンのリフレッシュをトリガーするアクションを実行します。- アプリがNotAuthorizedExceptionをキャッチし、期待通りにリダイレクトされることを確認します。## 本番環境でのベストプラクティスセキュリティとユーザー体験はバランスが重要です。銀行アプリなら24時間のリフレッシュトークンが標準的ですが、SaaSのダッシュボードなら30日から90日が適切でしょう。 セキュリティのヒント: これらのトークンを調整する際、テスト用に安全な管理者用認証情報が必要になることがあります。私はToolCraftのパスワードジェネレーターを使用しています。ブラウザ上でローカルに動作するため、生成されたシークレットがサーバーに送信されることはありません。AWS環境を扱う際には非常に重要です。

主なまとめ- アクセストークン vs リフレッシュトークン: アクセストークンは短期間の認可(1時間)用です。リフレッシュトークンは長期的な継続用です。- プロアクティブなサインアウト: リフレッシュトークンが期限切れになったときは、常にAuth.signOut()を使用して、LocalStorageから古いJWTをクリアしてください。- モニタリング: CloudWatchのTokenRefreshメトリクスを監視しましょう。失敗が急増した場合、通常は既存のユーザーセッションを壊してしまった設定変更が原因です。

Related Error Notes