JWTトークンにおけるTimestamp

JWTトークンで使用されるtimestamp:exp(有効期限)、iat(発行時刻)、nbf(有効開始時刻)。バリデーション、クロックスキュー、セキュリティのベストプラクティス。

Format

exp / iat / nbf

詳細な説明

JSON Web Token(JWT)は、トークンの有効性を制御する3つの標準クレームに、秒単位のUnix timestampを使用します。これらのクレームの理解は、安全な認証・認可の実装に不可欠です。

3つのtimestampクレーム:

{
  "iat": 1704067200,    // Issued At: トークンの発行時刻
  "nbf": 1704067200,    // Not Before: この時刻より前はトークンは無効
  "exp": 1704070800     // Expiration: この時刻以降はトークンは無効
}

RFC 7519で定められている通り、3つとも単位のUnix epochです。ここでミリ秒を使用するのはよくある間違いで、数千年先に有効期限切れとなるトークンが生成されます。

バリデーションロジック:

function validateJWT(payload) {
  const now = Math.floor(Date.now() / 1000); // 現在時刻(秒)

  if (payload.exp && now >= payload.exp) {
    throw new Error("Token expired");
  }

  if (payload.nbf && now < payload.nbf) {
    throw new Error("Token not yet valid");
  }

  // iatは情報提供用であり、通常バリデーションには使用しない
}

クロックスキューの許容:

分散システムでは、サーバーのクロックは完全には同期しません。サーバーAが発行したトークンは、サーバーBのクロックがわずかに遅れている場合、サーバーBでは未来から来たように見える可能性があります。これに対処するため、ほとんどのJWTライブラリは「クロック許容値」または「leeway」パラメータ(通常30〜60秒)を受け入れます。

// jose ライブラリの例
await jwtVerify(token, key, {
  clockTolerance: 60  // 60秒のクロックスキューを許容
});

セキュリティのベストプラクティス:

  • 常にexpクレームを設定してください。有効期限のないトークンは、漏洩した場合に永久に有効なままです。
  • アクセストークンの有効期間は短く設定してください(5〜15分)。長いセッションにはリフレッシュトークンを使用します。
  • 特定の将来の時刻にのみ有効になるべきトークン(例:事前スケジュールされたアクセス権限)にはnbfを使用してください。
  • セキュリティ判断にiatクレームを信用しないでください。これはトークン発行者の主張であり、偽造される可能性があります。

JWTのデバッグ: 認証失敗をデバッグする際は、常にトークンのexpと現在のサーバー時刻を比較してください。最も一般的な問題はトークンの期限切れであり、次に多いのが発行者と検証者の間のクロックスキューです。

ユースケース

OAuth 2.0認可サーバーは、アクセストークンに短いexp値を設定し、リソースサーバーでnbf/expを検証して、盗まれたトークンによるリプレイ攻撃を防ぐ必要があります。

Try It — Timestamp Converter

フルツールを開く