Webの状態をどこに保存する? Cookie・ローカルストレージ・サーバーセッションの選び分け

Webの状態を保存する場所は、ざっくり3つです。選び方の軸も3つで、「サーバーがその値を読む必要があるか」「いつ消えてよいか」「盗まれたら困るか」で決まります。結論を先に書くと、ログイン状態はサーバー側セッション+HttpOnly属性付きCookie、ダークモードや言語などの表示設定はローカルストレージ(Cookieが必要な場合もあります)、1つのタブで完結する入力途中のデータはセッションストレージが基本形です。以下で、3方式の違いと用途ごとの判断基準、個人情報を扱うときの確認点を整理します。
保存場所・有効期間・送信範囲の違い
まず3方式の性質を押さえます。違いが出るのは「どこに置かれるか」より、「リクエストに自動で付いてくるか」と「誰が読めるか」です。
- Cookie:保存場所はブラウザ。サーバーが
Set-Cookieヘッダーで発行でき、JavaScriptからも(HttpOnlyでなければ)読み書きできます。有効期間は Expires / Max-Age で指定し、どちらも指定しなければブラウザを閉じた時点で破棄されます。最大の特徴は、条件に合致するリクエストへ自動的に付与される点です。送信範囲は Domain・Path・SameSite で制御します。容量は1つあたり数KB程度しか入りません。 - ローカルストレージ/セッションストレージ:保存場所はブラウザ。オリジン(スキーム+ホスト+ポート)単位で区切られ、リクエストには自動送信されません。サーバーへ渡すにはJavaScriptで明示的に送る必要があります。ローカルストレージは明示的に消すまで残り、セッションストレージはタブを閉じるまでで、別タブとは共有されません。容量はCookieより大きく、数MB規模を扱えます。ただし保存時の暗号化は標準で求められていないため、端末上のデータは平文として扱うべきです(OWASP)。
- サーバー側セッション:実データはサーバー(メモリ、Redis、DBなど)にあり、ブラウザに渡るのはセッションIDだけです。有効期間はサーバー側で決められ、ログアウトや権限変更の際に即時無効化できます。値の中身をユーザーに触らせない唯一の方式です。
整理すると、Cookieは「サーバーと共有したい小さな値」、Web Storageは「クライアントだけで完結する値」、サーバー側セッションは「ユーザーに見せたくない・書き換えられたくない値」に対応します。
用途ごとの選び方
ログイン状態:サーバー側セッション+Cookie
認証情報はサーバー側に置き、ブラウザにはセッションIDだけを Secure・HttpOnly・SameSite 付きのCookieで渡す形が基本です。OWASPのセッション管理チートシートは、認証トークンやセッションID、JWT、リフレッシュトークンをローカルストレージやセッションストレージに保存しないよう明示しています。これらはオリジン内で動くすべてのJavaScriptから読めるため、XSSが1つあれば全トークンが漏れるからです。HttpOnly相当の防御手段がWeb Storageには存在しません。あわせて、ログイン直後にセッションIDを再発行する、ログアウト時はサーバー側のセッションも破棄する、といったライフサイクル管理も必要です。
表示設定:ローカルストレージ、ただしSSRならCookie
ダークモード、言語、閉じたお知らせバナーなど、サーバーが知らなくても成立する設定はローカルストレージが向きます。毎回のリクエストに値が乗らないぶん通信も軽くなります。
判断が分かれるのはサーバーサイドレンダリングを使う場合です。ローカルストレージはサーバーから読めないため、初回のHTML生成時にテーマを反映できず、描画後にテーマが切り替わるちらつきが起きます。初回レンダリングに必要な設定はCookieに置く、というのが実務上の分岐点です。
入力途中のデータ:セッションストレージ
複数ステップのフォームや申込ウィザードの一時保存には、タブを閉じれば消えるセッションストレージが適しています。別タブに引き継がれないため、同じフォームを2つ開かれたときの値の混線も避けられます。ただし氏名や連絡先などを含む下書きは、端末に残り続ける設計にしないことが前提です。
判断の順番
- サーバーがその値を読む必要があるか(必要ならCookieかサーバー側セッション)
- 改ざんや盗用が成立すると困るか(困るならサーバー側に本体を置き、Cookieには識別子だけ)
- タブごとに独立させたいか(したいならセッションストレージ)
- 数KBに収まるか(収まらないならサーバー側かWeb Storage)
- ユーザーが消しても業務が壊れないか(壊れるならクライアント保存に依存しない)
Cookieを使うときの属性の決め方
Cookieは属性の設定が安全性と動作のほぼすべてを決めます。MDNのリファレンスを踏まえると、最低限そろえる組み合わせは次のとおりです。
- Secure:HTTPSでのみ送信。HttpOnly:JavaScriptから読めなくする。認証用Cookieには両方必須です。
- SameSite:Strictは同一サイトのリクエストのみ、Laxは外部サイトからのリンク遷移などにも付与。CSRFへの部分的な防御になります。Chromium系は未指定時にLax相当を既定とします。
- 名前の接頭辞:
__Host-や__Secure-を付けると、条件を満たさないCookieはブラウザ側で拒否されます。改名だけで効くので採用コストが低い対策です。 - Domain・Path・Max-Age:いずれも最小限に。なおPathはアクセス制御の仕組みではないとMDNは注意しています。
- クロスサイト利用:埋め込みウィジェットなどで別サイト上から使うCookieは
SameSite=None; Secureに加えてPartitioned(CHIPS)を検討します。MDNは、PartitionedのないSameSite=Noneはクロスサイト文脈で将来ブロックされうると注意喚起しています。Partitionedは最上位サイトごとに別々の保存領域になるため、複数ドメインで共有する前提の設計は成立しません。
容量の制約も設計に効きます。Cookieが上限を超えると黙って破棄されるため、まとまったデータはサーバー側に置き、Cookieには識別子だけを載せる構成が安全です。
個人情報を扱うときの確認点
保存場所の選択と、法令上の確認事項は別の軸です。整理しておきたいのは次の3点です。
1. 外部送信規律は「保存場所」ではなく「端末から外部へ送らせる行為」を見る。電気通信事業法第27条の12は、利用者の端末に記録された情報を外部へ送信させるプログラム等(タグや情報収集モジュール)を対象とし、送信される情報の内容・送信先・利用目的について、通知・公表・同意取得・オプトアウト措置のいずれかで確認の機会を与えることを求めます。総務省のFAQは、Cookieを使っていなくても規律対象になりうること、自社が利用者識別のために発行したファーストパーティCookieのIDを自社へ送らせる分には確認の機会の付与が不要であることを示しています。つまり、CookieをローカルストレージやサーバーAPI経由の送信に置き換えても、外部へ送っている限り扱いは変わりません。
2. 自社サイトが対象かどうかは、ページ単位で考える。規律の対象は電気通信事業を営む者が提供する一定の役務(SNS、オンラインショッピングモール、検索、ニュースなど各種情報のオンライン提供)に限られます。総務省のFAQでは、小売業者が自社商品を売るサイトや会社案内ページ、来店予約ページは自己の需要として対象外とされる一方、同じサイト内のニュース配信ページは対象になると説明されています。「サイト全体で一律」ではない点が実務上のポイントです。
3. Cookie IDの取得経路と利用目的を説明できるようにしておく。個人情報保護法では、Cookie IDは個人情報ではなく個人関連情報として整理されてきました。2026年4月に閣議決定された改正法案では、電話番号・メールアドレス・Cookie IDなど特定の個人への働きかけが可能な情報を「連絡可能個人関連情報」と位置づけ、不適正利用と不正取得を禁止する規律が盛り込まれています。施行は公布から2年を超えない範囲で政令が定める日とされ、詳細は政省令・ガイドライン待ちです。いま着手して無駄にならないのは、どのCookie・識別子を、どこから取得し、何に使い、どこへ渡しているかの棚卸しです。
技術面では、ローカルストレージやセッションストレージが暗号化されない前提であることを忘れないでください。氏名・連絡先・注文内容などをそのまま端末に残す設計は、端末を共有する利用者やXSSの影響を直接受けます。
次に取る行動
- ブラウザの開発者ツールのApplicationパネルで、自社サイトが発行しているCookieとWeb Storageを一覧化する。
- 各項目に「誰が読むか/いつ消えるか/個人を識別しうるか/外部に送られるか」を記入し、保存場所が目的に合っているかを確認する。
- 認証に関わる値がWeb Storageにあれば、サーバー側セッション+Secure・HttpOnly・SameSite付きCookieへ移す計画を立てる。
- 外部へ送信しているタグを洗い出し、公表・同意取得の文面と実際の送信先・利用目的が一致しているかを突き合わせる。
保存場所の選択は、後から変えるほど影響範囲が広がります。新機能の設計時に上記の判断軸を適用し、決めた理由を残しておくと、法改正やブラウザの仕様変更が来たときの見直しが短時間で済みます。
出典
この記事に関連するchot Inc.の支援
chot Inc.は日本初のVercel公式パートナーとして、Next.jsを中心としたWebサイト・Webアプリケーションの開発を支援しています。Vercelの導入・契約・運用の見直しはVercel公式パートナー開発支援で、Next.jsによる新規開発や既存システムからの技術移行はモダンWeb開発で紹介しています。


