Webブラウザにおけるクライアントサイド永続化手法の比較

Webアプリケーションにおいて、ユーザーの状態や設定をクライアント側に一時的または長期的に保持する必要が生じる。これには複数の標準化されたメカニズムが存在し、それぞれ異なるスコープ、寿命、セキュリティ特性を持つ。

1. HTTP Cookie

Cookieは、HTTPプロトコルのステートレス性を補うために導入された初期の仕組みであり、主にサーバーとブラウザ間の状態管理を目的としている。サーバーからSet-Cookieヘッダーで送信され、その後のリクエストに自動付与される。

  • 容量制限:1ドメインあたり最大4KB、かつ通常20個まで(ブラウザ実装により差異あり)
  • ネットワーク負荷:すべてのHTTPリクエスト/レスポンスに含められるため、不要な通信オーバーヘッドが発生
  • 操作方法:JavaScriptではdocument.cookieで読み書き可能だが、XSS脆弱性への露出リスクが高い
  • セキュリティ属性:HttpOnly(JSアクセス不可)、Secure(HTTPSのみ送信)、SameSite(CSRF緩和)などにより制御可能
  • 有効期限:明示的なExpiresまたはMax-Ageが設定されていれば永続化され、未設定の場合はセッション終了時に破棄

2. localStorage

HTML5で導入されたWeb Storage APIの一部で、純粋なクライアント側データ保持を目的とする。サーバーとの通信には一切関与せず、完全にブラウザ内に閉じたストレージ空間である。

  • 容量:ほとんどのモダンブラウザで約5MB(ドメイン単位)
  • 永続性:明示的な削除(clear()removeItem())がない限り、ブラウザ再起動後も保持される
  • スコープ:同一オリジン(プロトコル+ホスト+ポート)内で共有される
  • 操作API:
const storage = window.localStorage;

// 文字列値の保存(keyとvalueは必ず文字列)
storage.setItem('theme', 'dark');

// 値の取得
const currentTheme = storage.getItem('theme');

// 特定キーの削除
storage.removeItem('tempData');

// 全データの初期化
storage.clear();

// キー一覧の取得(インデックス指定)
const firstKey = storage.key(0);

3. sessionStorage

localStorageと同様のAPIを持つが、ライフサイクルが「ページセッション」に束縛される点が本質的に異なる。タブまたはウィンドウ単位で独立したストレージ領域が確保される。

  • 生存期間:対応するブラウザタブ/ウィンドウが閉じられると即座に破棄される
  • 共有性:同一オリジンであっても、別タブ・別ウィンドウ間ではデータが隔離される
  • オブジェクトの格納:JSONシリアライズ/デシリアライズを用いて構造化データを扱える
const session = window.sessionStorage;

// 複雑なオブジェクトを保存する場合
const userInfo = { id: 1001, role: 'admin', lastLogin: Date.now() };
session.setItem('userProfile', JSON.stringify(userInfo));

// 復元
const raw = session.getItem('userProfile');
const parsed = raw ? JSON.parse(raw) : null;
console.log(parsed?.role); // "admin"

4. サーバーサイドセッション(補足)

Cookieとは密接に関連するが、実態はサーバー側に保持される状態管理機構である。ブラウザは単にセッション識別子(例:sessionid=abc123)をCookieとして保持し、各リクエストで送信するだけである。

  • 安全性:クライアントが内容を改竄できないため、認証トークンや権限情報などの機密データを格納できる
  • 依存関係:Cookieが無効化されている場合、セッション機能は動作しない(ただし、URLパラメータやヘッダー経由での代替手段も存在)
  • 運用要件:サーバー側でセッションの生成・検証・破棄・タイムアウト管理が必要

タグ: web-storage cookie localstorage sessionstorage http-session

5月22日 01:03 投稿