Featured image of post JWT(Json Web Token)認証と従来型セッション管理のセキュリティ比較 Featured image of post JWT(Json Web Token)認証と従来型セッション管理のセキュリティ比較

JWT(Json Web Token)認証と従来型セッション管理のセキュリティ比較

JWT認証と従来型セッション管理のセキュリティ比較と適切な運用パターンを徹底解説。ステートレスなJWTの利便性と強制ログアウトやトークン失効が困難なデメリットを天秤にかけ、アプリケーションの要件に最適な認証方式を選択するための実践的な指針を提供します。

はじめに

認証はすべてのWebアプリケーションの根幹です。ステートレスなJWT(JSON Web Token)認証ステートフルなセッション型認証は、どちらも「リクエストのたびに誰であるかを確認する」という目的を果たしますが、ストレージ方式、失効(revocation)、セキュリティ特性において根本的に異なります。本記事では両者を詳細に比較し、アプリケーションに適した方式を選択するための指針を提供します。


JWTの構造

JWTはbase64urlエンコードされた3つのセグメントをドットで連結した自己完結型のトークンです。

header.payload.signature
// ヘッダー
{ "alg": "HS256", "typ": "JWT" }
// ペイロード
{ "sub": "user123", "iat": 1712345678, "exp": 1712349278, "role": "admin" }
セグメント内容
Headerアルゴリズム(HS256, RS256)とトークン種別
Payloadクレーム — sub(subject)、iat(発行時刻)、exp(有効期限)、カスタムデータ
Signature改ざん検知のための署名

ペイロードはbase64エンコードされているだけで暗号化はされていません。機密情報をペイロードに含めてはいけません(JWEを使用する場合を除く)。


セッション型認証

セッション型認証では、サーバー側がセッションデータ(メモリ、Redis、データベース)を保持し、クライアントはセッションIDのみをCookieに保持します。

Client → Server: POST /login (credentials)
Server → Server: Create session (DB/Redisにデータ保存)
Server → Client: Set-Cookie: session_id=random_hash
Client → Server: GET /protected (Cookie付与)
Server → Server: セッションストアを検索
Server → Client: 200 OK

比較表

項目JWTセッション
データ保存場所クライアント側サーバー側
サーバー状態ステートレス — DB不要ステートフル — ストア問い合わせ必須
スケーラビリティ高い — 共有ストア不要Redis/DBの一元管理が必要
失効(revocation)困難 — expまで有効即時 — セッション削除
トークンサイズ大(数百バイト)小(セッションID ~32バイト)
XSS耐性JSからアクセス可能(localStorage)httpOnly CookieでJSから不可
CSRF対策手動対応が必要SameSite Cookie + CSRFトークン

JWTの失効問題

JWTの最大の弱点は**revocation(失効)**です。一度発行されたJWTはexpクレームに指定された時刻まで有効であり、ログアウト、パスワード変更、アカウント停止をしても即座に無効化できません。

対策パターン

1. 短期間アクセストークン + リフレッシュトークン:

// アクセストークン: 15分
// リフレッシュトークン: 7日(DB保存)

アクセストークンの有効期間を短くすることで、漏洩時の被害を局限します。リフレッシュトークンはサーバー側で管理されるため失効可能です。

2. トークンブラックリスト:

// ログアウト時にjti(JWT ID)をRedisに追加
await redis.set(`blacklist:${jti}`, 'true', 'EX', remainingTTL);

サーバー状態を部分的に導入しますが、全セッションではなく失効トークンのみを管理します。

3. 署名鍵の変更:

署名鍵を変更すると全トークンが無効化されます。緊急時の最終手段です。


XSSとCSRF

脅威JWT(localStorage)セッション(httpOnly Cookie)
XSSlocalStorageからトークンが漏洩JSからトークンにアクセス不可
CSRF影響なし(手動でAuthorizationヘッダ)SameSiteなしでは脆弱

JWTをlocalStorageに保存すると、XSS攻撃によりトークンが容易に盗まれます。httpOnly Cookieはこの問題を防ぎますが、Cookieは自動送信されるためCSRF対策が必要になります。

JWTのベストプラクティス: アクセストークンはhttpOnly, Secure, SameSite=StrictのCookieに保存し、サーバーはAuthorizationヘッダから読み取る(Cookieからは読まない)ことでCSRFを防止します。

res.cookie('token', jwt, {
  httpOnly: true,
  secure: true,
  sameSite: 'strict',
  maxAge: 15 * 60 * 1000
});

ハイブリッドアプローチ

多くのプロダクションシステムは両者を組み合わせています。

方式アクセストークンリフレッシュトークン
JWTのみJWT(メモリ保持)JWT(長期exp)
セッション型不透明なセッションID
ハイブリッド短期JWT(15分)不透明なリフレッシュトークン(DB保存)

ハイブリッドモデルは、大部分のリクエストでJWTのステートレス効率を活かしつつ、リフレッシュトークンによる失効機能を保持します。


選択の指針

優先事項推奨方式
サーバーDB負荷の最小化JWT(ステートレス)
即時ログアウト・アカウント停止セッション型
マイクロサービス / APIゲートウェイJWT(パススルー)
モバイルアプリJWT(Cookie非依存)
サーバーレンダリングWebアプリセッション(httpOnly Cookie)
サードパーティAPI公開JWT(Bearerトークン)

まとめ

JWTとセッション型認証に絶対的な優劣はありません。JWTは分散システム、モバイルアプリ、APIファーストアーキテクチャで威力を発揮します。セッション型認証はログアウト、失効、サーバー側セキュリティ制御において優れています。短期JWT + 失効可能なリフレッシュトークンのハイブリッドパターンは、両方の長所を活かし弱点を補う実用的な妥協策です。