はじめに
セッションを使って実装してって言われたはいいものの――「セッション」って一言で済ませられないくらい種類が多くて迷子に。最近、sessionStorage とサーバーサイドセッションを使い分ける場面があったので、実務でどう選ぶかを整理してみました。
セッションの種類と使い分け
1. HTTPセッション(サーバーサイド)
サーバー側のメモリに保存。セッションIDだけをCookieで渡す方式。
使うべき場面:
- ログイン状態の管理
- 機密情報の保持(個人情報など)
メリット/デメリット:
- ✅ セキュリティが高い
- ✅ サーバー側で強制破棄可能
- ❌ スケールアウト時にセッション共有が必要
- ❌ セッションレプリケーションのコストがかかる
2. Redisセッション
セッションデータをRedisに外部化。複数サーバー間で共有できる。
使うべき場面:
- 複数サーバーでのロードバランシング環境
- マイクロサービス間でのセッション共有
メリット/デメリット:
- ✅ スケールアウトが容易
- ✅ サーバー再起動してもセッション保持
- ❌ Redisの運用コストが必要
- ❌ ネットワークレイテンシが発生
3. Cookie
ブラウザに保存され、毎回HTTPリクエストに自動付与される。
使うべき場面:
- セッションID
- 言語設定などの軽い設定値
- トークン保存(httpOnly, Secure属性付き)
メリット/デメリット:
- ✅ サーバーへのリクエスト時に自動送信
- ✅ httpOnly属性でJSからのアクセスを制限可能
- ❌ サイズ制限が厳しい(4KB程度)
- ❌ CSRF攻撃のリスク(対策必要)
4. sessionStorage
ブラウザのメモリに保存。タブを閉じたら消えるのが特徴。
使うべき場面:
- フォーム入力の一時保存
- 外部サイト遷移時の状態保持
- ウィザード形式の画面遷移データ
メリット/デメリット:
- ✅ タブごとに独立
- ✅ サーバーに送信されない(通信量削減)
- ✅ 容量が大きい(5-10MB)
- ❌ タブを閉じたら消える
- ❌ JavaScriptから読み書き可能(XSS対策必須)
実装例:
// 外部サイト遷移前に保存
sessionStorage.setItem('access-token', token);
// 戻ってきた後に復元
const token = sessionStorage.getItem('access-token');---
5. localStorage
ブラウザに永続的に保存。明示的に削除しない限り残る。
使うべき場面:
- ユーザー設定(テーマ、言語等)
- ドラフト保存
- オフライン機能のキャッシュ
メリット/デメリット:
- ✅ 永続的に保存される
- ✅ 容量が大きい(5-10MB)
- ❌ XSSで盗まれるリスク(機密情報NG)
- ❌ 複数タブで共有される(予期しない動作の原因に)
6. JWT (JSON Web Token)
ステートレスな認証方式。トークン内に情報を含む。
使うべき場面:
- REST API認証
- SPA(Single Page Application)
- モバイルアプリの認証
メリット/デメリット:
- ✅ サーバー側でセッション管理不要
- ✅ スケールアウトが容易
- ❌ 強制的な無効化が困難
- ❌ トークンが盗まれるとリスク大
実務での使い分けフローチャート
❌ セッションレプリケーション前提の大きなデータ
// NG例
session.setAttribute("largeData", hugeObject); // 数MB理由: セッションレプリケーションの負荷が高すぎる。大きなデータはDB等に保存。
まとめ
| 種類 | 保存場所 | 永続性 | 用途 |
|---|---|---|---|
| HTTPセッション | サーバー | 再起動で消える | ログイン状態、機密情報 |
| Redisセッション | Redis | 永続化可能 | 複数サーバー共有 |
| Cookie | ブラウザ | 有効期限まで | セッションID、設定値 |
| sessionStorage | ブラウザ | タブを閉じたら消える | 一時的な状態、外部遷移時 |
| localStorage | ブラウザ | 半永久的 | ユーザー設定、キャッシュ |
| JWT | ブラウザ/サーバー | 有効期限まで | API認証、ステートレス |
覚えておくべき原則:
- 機密情報は必ずサーバーサイド
- 一時的な状態はsessionStorage
- 永続的な設定はlocalStorage or Cookie
- API認証はJWT(適切な有効期限設定必須)
実装時はセキュリティ要件とスケーラビリティを考慮して選択しましょう!