ブラウザ、Cookieやセッション、ブラウザとサーバーのストレージを活用し違いを知る

javascript
この記事は約27分で読めます。

現代のウェブアプリケーションは、ユーザーのデータを保持するためにさまざまな方法でストレージを活用します。これにより、ユーザーがブラウザを閉じたり、再度アクセスしたりしても、以前のデータや設定を再利用できるようになります。ブラウザが提供するストレージ機能は、以下のような特徴があります。

  1. クライアントサイドでのデータ保持
    データはクライアントのブラウザ内に保存され、サーバーとの通信が不要な場合でも利用可能です。
  2. さまざまな用途に適した選択肢
    セッションごとにデータを保持するものから、永続的に保存可能なものまで、用途に応じた選択肢があります。

ブラウザストレージの種類別

ブラウザが提供するストレージは、主に以下の4つのタイプに分類されます。それぞれの特徴や注意点使い方について解説します。

Cookie(クッキー)

特徴

  • 最も古くから存在するストレージ方式。
  • クライアントとサーバー間でのデータ通信に適している。
  • 通常はサイズ制限があり、1つのドメインにつき約4KB

主な用途

  • ユーザー認証(セッションIDの保存など)。
  • サイト訪問状況の追跡(トラッキング)。

制限

  • サーバーとの通信時に自動的に送信されるため、通信量に影響を与える。
  • ユーザーによって簡単に削除される可能性がある。

JavaScriptでの操作例

// Cookieの設定
document.cookie = "username=JohnDoe; path=/; expires=Fri, 31 Dec 2025 23:59:59 GMT";

// Cookieの取得
console.log(document.cookie);

// Cookieの削除
document.cookie = "username=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT";
JavaScript

確認手順

  1. ブラウザ検証ツールを開く:
    • Chrome/Edgeの場合: Ctrl + Shift + I(Windows)または Cmd + Option + I(Mac)。
    • Firefoxの場合: Ctrl + Shift + I(Windows)または Cmd + Option + I(Mac)。
  2. Application タブを選択:
    • メニューから Application を選択します。
  3. 左サイドバーで Storage > Cookies を選択:
    • 「Cookies」をクリックすると、現在のドメインに関連付けられたCookieのリストが表示されます。
    • 他のドメインのCookieを見る場合は、ドメインを選択してください。

表示される情報

  • Name: Cookieのキー名。
  • Value: Cookieの値。
  • Domain: Cookieが有効なドメイン。
  • Path: Cookieが有効なパス。
  • Expires/Max-Age: Cookieの有効期限。
  • Size: Cookieのデータサイズ。
  • HTTPOnly / Secure: セキュリティ属性の設定。

LocalStorage(ローカルストレージ)

特徴

  • 永続的にデータを保存するためのストレージ。
  • 短いコードでデータの保存・取得・削除が可能です。
  • ユーザーが手動で削除するまでデータは保持される。
  • データ容量は通常約5MB
  • 小規模なアプリケーションや設定の保存に最適です。

主な用途

  • ユーザー設定の保存(テーマや言語の選択)。
  • 一時的なアプリケーションデータの保存。

制限

  1. 容量制限
    通常、5MB程度の容量制限があるため、大量のデータには向いていません。
  2. 同期処理
    LocalStorageは同期的にデータを処理するため、大規模データの操作はパフォーマンスに影響を与える可能性があります。
  3. セキュリティ
    保存したデータは暗号化されておらず、JavaScriptで簡単にアクセスできるため、機密データの保存には不向きです。

JavaScriptでの操作例

// データの保存
localStorage.setItem("username", "JohnDoe");

// データの取得
console.log(localStorage.getItem("username"));

// データの削除
localStorage.removeItem("username");

// 全てのデータを削除
localStorage.clear();
JavaScript

確認手順

  1. Application タブを選択
    • 検証ツール内で Application を選択します。
  2. 左サイドバーで Storage > Local Storage を選択
    • 「Local Storage」をクリックします。
  3. ドメインを選択
    • 現在開いているウェブサイトのドメインを選択すると、LocalStorageのキーと値が表示されます。

表示される情報

  • Key: LocalStorageに保存されたキー。
  • Value: キーに対応する値。

ユーザー設定の保存

以下は、LocalStorageを使用してダークモード設定を保存・読み込みする例です。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>ダークモード切り替え</title>
  <style>
  /* 通常モード(ライトモード)のスタイル */
  body {
    background-color: white;
    color: black;
    transition: background-color 0.3s, color 0.3s; /* スムーズな切り替え */
  }

  /* ダークモードのスタイル */
  body.dark-mode {
    background-color: rgb(39, 39, 39);
    color: white;
  }
</style>
</head>
<body>
  <h1 id="modeText">ライトモードです</h1>
  <button id="toggleTheme">テーマを切り替え</button>

  <script>
    // ページ読み込み時にテーマを適用
    document.addEventListener("DOMContentLoaded", () => {
      const theme = localStorage.getItem("theme");
      const modeText = document.getElementById("modeText");

      if (theme === "dark") {
        document.body.classList.add("dark-mode");
        modeText.textContent = "ダークモードです"; // ダークモードに合わせて文字を変更
      } else {
        modeText.textContent = "ライトモードです"; // ライトモード時の文字
      }
    });

    // ボタンをクリックしてテーマを切り替え
    document.getElementById("toggleTheme").addEventListener("click", () => {
      const isDarkMode = document.body.classList.toggle("dark-mode");
      const modeText = document.getElementById("modeText");

      // テーマに応じて文字とLocalStorageの値を切り替え
      if (isDarkMode) {
        localStorage.setItem("theme", "dark");
        modeText.textContent = "ダークモードです";
      } else {
        localStorage.setItem("theme", "light");
        modeText.textContent = "ライトモードです";
      }
    });
  </script>
</body>
</html>
HTML

このコードでは、LocalStorageにユーザーが選択したテーマ(ライトまたはダーク)を保存し、次回ページ読み込み時に適用します。

ショッピングカート機能

LocalStorageを活用して、シンプルなショッピングカートを作成する例を示します。

// 商品をカートに追加
function addToCart(itemId, itemName, itemPrice) {
  const cart = JSON.parse(localStorage.getItem("cart")) || [];
  cart.push({ id: itemId, name: itemName, price: itemPrice });
  localStorage.setItem("cart", JSON.stringify(cart));
  console.log("カートに追加されました:", cart);
}

// カートの内容を表示
function displayCart() {
  const cart = JSON.parse(localStorage.getItem("cart")) || [];
  console.log("現在のカート:", cart);
}

// 商品を追加
addToCart(1, "商品A", 1000);
addToCart(2, "商品B", 2000);

// カートの内容を表示
displayCart();
JavaScript

SessionStorage(セッションストレージ)

特徴

  • ブラウザタブごとにデータを保持。
  • タブを閉じるとデータが削除される。
  • データ容量は通常約5MB

主な用途

  • ページ間での一時的なデータ共有。
  • ユーザーが特定のページで実行している操作の追跡。

JavaScriptでの操作例

// データの保存
sessionStorage.setItem("sessionID", "12345");

// データの取得
console.log(sessionStorage.getItem("sessionID"));

// データの削除
sessionStorage.removeItem("sessionID");

// 全てのデータを削除
sessionStorage.clear();
JavaScript

確認手順

  1. Application タブを選択:
    • 検証ツール内で Application を選択します。
  2. 左サイドバーで Storage > Session Storage を選択:
    • 「Session Storage」をクリックします。
  3. ドメインを選択:
    • 現在開いているウェブサイトのドメインを選択すると、SessionStorageのデータが表示されます。

表示される情報:

  • Key: SessionStorageに保存されたキー。
  • Value: キーに対応する値。

注意:

  • SessionStorageは現在のタブでのみ有効です。別のタブで開いた場合やリロード後はデータが異なる場合があります。

IndexedDB(インデックス付きデータベース)

特徴:

  • 大量の構造化データを効率的に保存可能。
  • 非同期APIを使用するため、パフォーマンスに優れている。
  • データ操作時にトランザクションを使用するため、データの一貫性を保ちやすい。
  • データ容量はブラウザやデバイスによって異なるが、数百MBから数GB

主な用途:

  • 高度なウェブアプリケーションのデータストレージ。
  • オフラインアプリケーション(例: メモ帳アプリやカレンダー)。

JavaScriptでの基本操作

// IndexedDBのデータベースを開く
const request = indexedDB.open("MyDatabase", 1);

// データベースが初期化されていない場合の処理
request.onupgradeneeded = function(event) {
  const db = event.target.result;
  const objectStore = db.createObjectStore("users", { keyPath: "id" });
  objectStore.createIndex("name", "name", { unique: false });
};

// データベースへの接続が成功した場合
request.onsuccess = function(event) {
  const db = event.target.result;

  // トランザクションの作成とデータの追加
  const transaction = db.transaction(["users"], "readwrite");
  const objectStore = transaction.objectStore("users");
  objectStore.add({ id: 1, name: "John Doe" });

  transaction.oncomplete = function() {
    console.log("データが保存されました");
  };
};
JavaScript

商品の検索

IndexedDBを使って保存した商品データを検索する例です。

request.onsuccess = function(event) {
  const db = event.target.result;

  // 商品を名前で検索
  const transaction = db.transaction(["products"], "readonly");
  const objectStore = transaction.objectStore("products");
  const index = objectStore.index("name");
  const searchRequest = index.get("商品A");

  searchRequest.onsuccess = function() {
    console.log("検索結果:", searchRequest.result);
  };
};
JavaScript

確認手順:

  1. Application タブを選択
    • 検証ツール内で Application を選択します。
  2. 左サイドバーで Storage > IndexedDB を選択
    • 「IndexedDB」をクリックします。
  3. データベースを選択
    • 現在のドメインで使用しているIndexedDBのデータベースがリスト表示されます。
    • データベース名をクリックすると、各オブジェクトストア(テーブルに相当)に保存されているデータを確認できます。
  4. データの確認
    • オブジェクトストアをクリックすると、中に保存されたデータが表示されます。

表示される情報:

  • データベース名: 使用中のデータベース名。
  • オブジェクトストア: 各ストアのデータがJSON形式で表示されます。
  • データ: キーと値のペアで保存されたデータ。

よく使うストレージの比較

特徴CookieLocalStorageSessionStorageIndexedDB
保存期間設定次第永続的タブを閉じるまで永続的
保存可能なデータ量約4KB約5MB約5MB数百MB〜数GB
アクセス方式同期的同期的同期的非同期的
主な用途認証・トラッキング設定の保存一時的データ大量データの保存

ブラウザごとの注意点

  • Chrome/Edge
    • データ表示は比較的詳細でわかりやすい。
    • IndexedDBのデータはJSON形式で簡単に確認可能。
  • Firefox
    • 同様に「ストレージ」タブでデータを確認可能。
    • 一部の情報がやや異なる形式で表示される場合があります。

まとめ:検証ツールで見るべき場所

ストレージ種類確認場所(検証ツール)表示内容
CookieApplication > Storage > Cookiesキー、値、ドメイン、期限など
LocalStorageApplication > Storage > Local Storageキーと値
SessionStorageApplication > Storage > Session Storageキーと値
IndexedDBApplication > Storage > IndexedDBデータベース、オブジェクトストア、データ

設計の違い

document.cookie が document を通じてアクセス可能な理由

cookie は HTTPプロトコルの一部として設計され、Webの初期段階からサーバーとクライアント間でデータをやり取りする仕組みとして存在しています。そのため、以下の理由で document.cookie は document オブジェクトの一部として提供されています。

HTMLドキュメントとの関連性
Cookieは、Webページ(HTMLドキュメント)と密接に関連付けられています。クライアントとサーバー間で状態を保持するための仕組みとして、HTTPリクエストとレスポンスに含まれることが標準です。

スコープの設計
Cookieは、基本的にブラウザとサーバーが共有する「ドメイン単位」のデータであり、その利用範囲がHTMLドキュメント(document オブジェクト)に限定されるよう設計されています。

仕様の歴史的背景
CookieはWebの初期から存在しており、JavaScriptの初期仕様に組み込まれていました。その結果、document.cookie を通じてデータの読み書きができるようになっています。

sessionStorage や localStorage が document に属していない理由

sessionStorage と localStorage は、HTML5で導入された「Web Storage API」の一部であり、設計の思想が cookie とは異なります。

  1. 独立したデータ管理の設計
    Web Storage API は、クライアントサイドのデータ管理を効率化するために作られたもので、Cookieの制約(サイズやセキュリティ面)を克服することを目的としています。
    document のスコープに含めるのではなく、独立した専用のAPI(window.sessionStorage や window.localStorage)として提供されています。
  2. スコープの広がり
    • sessionStoragelocalStorage は、HTMLドキュメントに直接結びつくものではなく、ブラウザ全体の「ウィンドウオブジェクト(window)」に属します。
    • これにより、JavaScript全体からアクセス可能な汎用的なデータ管理手段として利用できます。
  3. 利用の明確化
    document はHTMLドキュメント(DOMツリー)に直接関連付けられています。一方、Web Storage APIは「状態管理」に特化しており、HTMLドキュメントとは独立しています。この設計により、Cookieのようなページ固有ではなく、より広範囲なデータ管理を可能にしています。

indexedDB が document に属していない理由

indexedDB は、さらに高度なデータ管理のための仕組みとして設計されており、その性質上、document から直接管理するべきではないと考えられています。

  1. ローカルデータベースの役割
    indexedDB は、クライアントサイドで大量の構造化データを扱うためのデータベースとして設計されています。
    • DOMやHTMLドキュメントの一部ではなく、ローカルストレージ領域全体でのデータ管理を目的としています。
    • そのため、HTMLやDOMに紐付ける必要がなく、window オブジェクトを通じて独立したAPIとして提供されています。
  2. 高い独立性と非同期設計
    • indexedDB は非同期APIを採用しており、ブラウザ内での複雑なデータ操作に適しています。
    • document は同期的にDOM操作を行うためのインターフェイスであり、非同期操作を要求するデータベースAPIを含めるべきではないという設計意図があります。
  3. スコープの違い
    • indexedDB は、ブラウザ全体で共有可能なデータベース(オリジンごとに分離)として機能します。
    • HTMLドキュメントに特化した document とは異なり、より大きなスコープを対象としています。

SessionとCookieとは?

Session と Cookie は、ウェブアプリケーションがユーザーに関する情報を一時的または永続的に保持するための2つの仕組みです。それぞれの役割や使い方は異なり、用途によって選択されます。

Cookieの概要

Cookieは、ウェブブラウザに保存される小さなデータ片です。ユーザーがブラウザを閉じた後もデータを保持するため、次回アクセス時に再利用できます。重複になりますが特徴と主な用途です。

特徴

  • 保存場所: クライアント側(ブラウザ)。
  • サイズ: 通常、各Cookieは4KBまで、1ドメインにつき20個程度が推奨。
  • 有効期限: 任意で設定可能(例: 永続CookieやセッションCookie)。
  • 送信: 毎回、リクエストと一緒にサーバーに送信される。

主な用途

  1. ユーザー認証: ログイン状態の維持(例: 「ログイン状態を保持する」)。
  2. トラッキング: ユーザー行動の追跡(広告、アナリティクス)。
  3. 設定の保存: 言語選択、テーマ設定。

Cookieの作成方法 (PHP例)

// Cookieのセット
setcookie("username", "JohnDoe", time() + (86400 * 30), "/"); // 30日間有効

// Cookieの読み取り
if (isset($_COOKIE['username'])) {
    echo "ようこそ " . $_COOKIE['username'] . " さん";
}

// Cookieの削除
setcookie("username", "", time() - 3600, "/");
PHP

JavaScriptでのCookie操作

// Cookieの作成
document.cookie = "theme=dark; path=/; expires=Fri, 31 Dec 2025 23:59:59 GMT";

// Cookieの読み取り
console.log(document.cookie);

// Cookieの削除
document.cookie = "theme=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT";
JavaScript

Sessionの概要

Sessionは、サーバー側で管理されるユーザー情報の保存機能です。ユーザーごとに一意の識別子(セッションID)が生成され、それを元に情報が管理されます。

特徴

  • 保存場所: サーバー側。
  • データ量: サーバーの容量に依存(Cookieより大規模なデータが可能)。
  • 有効期限: ブラウザを閉じるまで(デフォルト)または明示的に設定可能。
  • アクセス: クライアントはセッションIDをCookieやURLパラメータとして送信。

主な用途

  1. ユーザー認証: ログインセッションの管理。
  2. ショッピングカート: 一時的な商品情報の保存。
  3. 動的なデータ保持: 一時的な入力データや状態の保存。

Sessionの作成方法 (PHP例)

// セッションの開始
session_start();

// データの保存
$_SESSION['username'] = "JohnDoe";

// データの取得
if (isset($_SESSION['username'])) {
    echo "セッションユーザー: " . $_SESSION['username'];
}

// セッションIDを表示
echo "セッションID: " . session_id();

// セッションの削除
session_unset(); // 全てのセッションデータを削除
session_destroy(); // セッションを破棄
setcookie("PHPSESSID", "", time() - 3600, "/"); // セッションIDを保持するCookieを削除
PHP

セッションデータ自体は サーバー側 に保存され、ブラウザにはランダムな値の セッションID が保存されます。

CookieとSessionの違い

特徴CookieSession
保存場所クライアント側(ブラウザ)サーバー側
データサイズ約4KB(制限あり)サーバー容量に依存(制限なし)
有効期限指定可能ブラウザ閉鎖時または指定まで
セキュリティ中身がクライアントに見えるサーバー側で管理されるため安全
ユースケース永続的な設定や情報(例: ログイン)一時的なセッション情報(例: カート)

CookieとSessionのセキュリティ

Cookieのセキュリティ対策

HTTP Only
CookieをHTTPプロトコルのみで使用し、JavaScriptでのアクセスを防ぐ。

setcookie("username", "JohnDoe", time() + (86400 * 30), "/", "", true, true);
JavaScript

Secure属性
HTTPS接続のみでCookieを送信。

setcookie("username", "JohnDoe", time() + (86400 * 30), "/", "", true);
JavaScript

暗号化
Cookieに保存するデータを暗号化し、改ざんを防ぐ。
CSRFトークン
フォーム送信時にトークンを利用して、不正なリクエストを防ぐ。

Sessionのセキュリティ対策

セッションハイジャック対策
セッションIDを頻繁に更新する。

session_regenerate_id(true);
PHP

セッション固定攻撃対策
セッションIDをユーザー認証後に再生成する。
HTTPSの使用
セッションIDが盗まれないよう、常にHTTPSで通信を行う。
有効期限の設定
セッションに適切な有効期限を設ける。

CookieとSessionを組み合わせた例

以下は、CookieでセッションIDを保存し、サーバー側でセッション管理を行う例です。

// セッション開始
session_start();

// 初回アクセス時にセッションデータを保存
if (!isset($_SESSION['visit_count'])) {
    $_SESSION['visit_count'] = 0;
}
$_SESSION['visit_count']++;

// CookieにセッションIDを保存
setcookie("PHPSESSID", session_id(), time() + 3600, "/");

// 表示
echo "訪問回数: " . $_SESSION['visit_count'];
PHP

CookieとSessionを選ぶ基準

  • 永続的なデータ保存が必要: Cookieを使用。
  • 一時的なセッション情報が必要: Sessionを使用。
  • セキュリティが重要: サーバーサイドのSessionを優先。

Sessionデータ確認の流れ

Session のデータは、一般的にはブラウザの検証ツール(DevTools)では直接確認できません。これは、Session のデータがサーバー側に保存される仕組みだからです。SessionはユーザーのセッションID(通常、Cookie内に保存される)を基に、サーバーで関連付けられた情報を管理します。

ただし、Sessionの関連情報を確認したりデバッグするために、以下の手順を使用できます。

セッションIDの確認(Cookie内に保存される場合)

セッションIDは、サーバー側でSessionを識別するために利用される一意の識別子です。このセッションIDがCookieとしてクライアント側に保存される場合、ブラウザの検証ツールで確認できます。

確認手順:

  1. 検証ツールを開く
    • Ctrl + Shift + I(Windows)または Cmd + Option + I(Mac)でブラウザの検証ツールを開きます。
  2. Application タブを選択
    • 検証ツール内で Application タブを選択します。
  3. Cookies を選択
    • 左サイドバーの Storage > Cookies をクリックし、現在アクセスしているドメインを選びます。
  4. PHPSESSIDなどのセッションIDを探す
    • 一般的なPHPでは、セッションIDは PHPSESSID という名前のCookieに保存されます。
    • Key: PHPSESSID
    • Value: セッションID(例: abc123xyz456)

サーバー側のセッションデータの確認

セッションIDがわかったら、サーバー側でそのIDに関連付けられたデータを確認することができます。

確認手順(PHPの場合)

  • セッションファイルの保存先を確認
    PHPでは、セッションデータはデフォルトでサーバー上の tmp ディレクトリ(例: /tmp)にファイルとして保存されます。
    セッションファイルの名前は通常 sess_セッションID の形式です。
  • PHPコードでデバッグ
    セッションデータをデバッグしたい場合は、以下のようにセッションの内容を出力します。
session_start();
echo '<pre>';
print_r($_SESSION);
echo '</pre>';
PHP

SessionがCookieとは異なる点

特徴CookieSession
保存場所クライアント側(ブラウザのCookie)サーバー側(セッションストレージ)
データサイズ小容量(通常4KB以下)サーバーの容量に依存(大規模データ対応)
有効期限設定可能(例: 30日間)ブラウザを閉じると終了(デフォルト)
セキュリティクライアントに見えるサーバー側で管理されるため安全性が高い

よくある質問

セッションデータがブラウザで見えない理由は?

Sessionはクライアントではなくサーバー側でデータを保持します。クライアントにはセッションIDだけが送信され、それを使ってサーバーが必要なデータを参照します。このため、セッションデータそのものはブラウザから見えません。


セッションデータがCookieに保存される場合は?

特定のサーバー設定やフレームワークでは、セッションデータを直接Cookie内に保存する場合もあります(例: JSON Web TokensやCookieセッションストレージ)。この場合は、Application > Cookies でデータを確認できます。

セッションデータが保存されない理由は?

  • セッションが適切に開始されていない(session_start() が不足)。
  • クッキーが無効になっている。
  • サーバーのセッション保存ディレクトリに書き込み権限がない。
  • セッションの有効期限が短すぎる。

まとめ

この記事では、PHPセッション管理やブラウザストレージについて詳しく解説しました。セッションはサーバー側でデータを管理し、セッションIDがランダムな値としてクライアントのCookieに保存される仕組みです。セッションデータの削除方法として、セッション変数を空にするsession_unset()、サーバー上のセッションデータを破棄するsession_destroy()、そしてクライアント側のセッションIDを削除するsetcookie()を組み合わせる手順を紹介しました。

また、ブラウザストレージ(Cookie、LocalStorage、SessionStorage、IndexedDB)の種類と用途、それぞれの確認方法についても解説しました。さらに、LocalStorageを活用したダークモード切り替えの実装例や、セッションIDの安全な管理方法も具体的に紹介しています。

一時的なデータの補完には、用途に応じた選択が重要です。サーバー側でセキュリティが必要ならセッション、クライアントで軽量データを管理するならLocalStorageやSessionStorageを選びましょう。一方、データの永続性が必要ならCookieが有効です。目的に応じて適切な方法を使い分けることで、効率的かつ安全な開発が可能になります。

セッションやブラウザストレージを正しく理解し、安全で効率的に活用することで、より使いやすいウェブアプリケーションを構築できるようになる内容です。

コメント