Cookieを完全に理解したい
はじめに¶
エンジニアとかをやっていると Cookie という名前は聞いたことがあると思います。 「なんか保存しているもの」とかぐらいのイメージの人が多いのではないでしょうか。
この記事では「なぜ Cookie が必要なのか」から順番に整理して、EC サイト・ログイン・広告という 3 つの場面で Cookie がどう使われているかを見ていきます。
Web の通信とステートレス¶
私たちは日頃から Web サイトに対して何かをして、その結果をうけて内容を表示します

ここの通信のやり取りは、HTTPという通信プロトコルを利用して実現しています しかし、HTTPはステートレスであるという特徴を持つので状態をもちません
:::message HTTP はステートレス(状態を持たない) 1往復が終わると、サーバーはそのブラウザのことをすぐ忘れます。次のリクエストが来ても「初対面のお客さん」として扱います :::
Cookie はこのステートレスな HTTP において、ステートフルなやりとりを実現する仕組みです。 サーバーがブラウザに「メモ」を渡し、ブラウザが毎回そのメモを持参することで、サーバーは「前回と同じ相手」を把握できます。
我々がよく利用する Web サービスの多くは、事実上ステートフルです。 ログイン状態の維持、カートの保持、設定の記憶など、「前回の続き」がなければ快適に使えないものばかりです。 それを実現しているのが Cookie という仕組みです。
具体的にいうと以下のような場面で利用されています。
- ログイン機能があるWebサイト
- EC サイトなどのカートの情報
- 広告
Cookie とは¶
Cookie とは「サーバーがブラウザに渡す小さなテキストデータ」です。
まずサーバーが Set-Cookie というヘッダーでブラウザに「これ覚えておいて」と渡します。
ブラウザはそのデータを保存しておいて、次に同じサーバーへリクエストする時に、リクエストヘッダーに Cookie を自動で追加して送ります。
sequenceDiagram
actor U as ユーザー
participant B as ブラウザ
participant S as サーバー
U->>B: サイトを開く
B->>S: GET /(初回リクエスト)
S-->>B: 200 OK + Set-Cookie: cart_id=xyz123
Note over B: cart_id=xyz123 を保存
U->>B: 別のページを開く
B->>S: GET /cart + Cookie: cart_id=xyz123
Note over B: 自動で Cookie を付けて送る
S-->>B: 200 OK(同じブラウザと識別できた)
ポイントは 2 つです。
- 自動で送る:ユーザーが何か操作するわけではなく、ブラウザが自動でやってくれます
- サーバーが発行する:ブラウザが勝手に作るわけではなく、必ずサーバーから
Set-Cookieで渡されます
ブラウザに Cookie の情報が保存されるので、ブラウザの変更(ChromeからSafariなど)やシークレットモードでは Cookie が引き継がれず、ログイン状態なども保持されません。
Cookie の利用場面¶
Cookie が実際にどう使われているか、3 つの場面で見ていきます。
- EC サイト — 未ログインでもカートを引ける
- ログイン — Session ID を運んで認証状態をつなぐ
- 広告 — 閲覧履歴を文脈として使う
どれも発想は同じで、前回の手がかりを次回のリクエストに載せることが共通しています。
1. EC サイトにおける Cookie¶
ログインしていなくても、Cookie でそのブラウザのカートを識別できます。
- 初回訪問:サーバーがカート識別子を発行(
Set-Cookie: cart_id=xyz) - 商品を追加:ブラウザが cart_id を自動送信(
Cookie: cart_id=xyz) - 後日アクセス:同じ ID から前回のカートを復元(未ログインでも「続き」が見える)
:::message Cookie に入っているのは「カートの中身そのもの」ではなく、カートを引くための ID であることがポイントです。実際の商品一覧や数量はサーバー側で管理されます。 :::
EC サイトで注目する Set-Cookie 属性¶
| 属性 | 例 | 役割 |
|---|---|---|
| Cookie 名と値 | cart_id=xyz |
カートを引く識別子 |
| 有効期限 | Max-Age=2592000 |
ブラウザを閉じた後もカートを残す |
| HTTPS 限定 | Secure |
HTTPS 通信だけに限定する |
| JS からの読取制限 | HttpOnly |
XSS 経由の露出を減らす |
Cookie 単体でも theme=dark(表示設定)や lang=ja(言語設定)のような小さな値は持てます。
ただし、ユーザーの認証状態や詳細なカートの中身まで Cookie に全部入れるのは危険です。そこで登場するのが Session ID との組み合わせです。Cookie には短い ID だけ入れて、その ID に紐づくデータはサーバー側で管理します。Cookie は「鍵」を運び、「金庫の中身」はサーバーが持つイメージです。
2. ログインにおける Cookie¶
ログインの主役は認証とセッション管理です。Cookie はその結果として発行された Session ID を運ぶ役を担います。
| 仕組み | 役割 |
|---|---|
| Cookie | 「このブラウザは誰の続きか」の手がかりを送る |
| セッション | ログイン中か、有効期限内かをサーバーが判定する |
ログイン後に別ページへ移動しても本人だと分かるのは、Cookie が Session ID を毎回自動で送り返しているからです
Session ID はどうやって検証するのか¶
Session ID は crypto.randomUUID() などで生成した推測不可能な文字列です。
サーバー側では Redis やデータベースに session_id → ユーザー情報 のマッピングを保存しておき、リクエストのたびに照合します。
- 存在しない ID が来た場合 → ログアウト状態として扱う(401 を返すなど)
- 有効期限が切れた ID が来た場合 → 同様にログアウト扱い
- 一定時間操作がないとタイムアウトして自動ログアウトするのもこの仕組みです
ここにログイン後の DevTools > Application > Cookies で session_id が保存されているスクリーンショットを置いて
ログイン時に設定する Set-Cookie 属性¶
| 属性 | 例 | 役割 |
|---|---|---|
| Cookie 名と値 | session_id=abc |
認証済みセッションを引くための鍵 |
| JS からの読取制限 | HttpOnly |
XSS 経由で Session ID が盗まれにくくなる |
| HTTPS 限定 | Secure |
HTTPS のときだけ送る |
| クロスサイト制御 | SameSite=Lax |
別サイトからの POST に session_id が送られない。CSRF 対策として機能する |
:::message
なぜ SameSite が CSRF 対策になるのか
session_id を Cookie で管理していると、ブラウザは利用者の意思とは別にその値を自動で送ります。つまり、利用者がログインしたまま悪意のある外部サイトを開き、そこで意図しない POST が発生すると、ブラウザは session_id を付け、サーバーはそれを「正しいログイン済みユーザーからの操作」と誤認しうるわけです。これが CSRF の基本的な危険です。
厳密には、CSRF は session_id 自体を盗まなくても成立します。session_id を script などで盗まれるのは XSS やセッションハイジャックの話で、そちらには HttpOnly が重要です。一方の CSRF では、ログイン中ブラウザが外部サイト経由のリクエストにも Cookie を自動で添えてしまうことが本質です。SameSite=Lax は、そうした別サイト起点の POST に session_id を送りにくくすることで、攻撃を成立しにくくします。
IPA の 安全なウェブサイトの作り方 - 1.6 CSRF(クロスサイト・リクエスト・フォージェリ) でも、ログインした利用者からのリクエストが「その利用者が意図したものか」を識別できないと問題になると整理されています。 :::
ログアウトの流れ¶
sequenceDiagram
participant B as ブラウザ
participant S as サーバー
B->>S: POST /logout
Note over S: セッションを破棄(DBから削除)
S-->>B: レスポンス + Max-Age=0 でCookie削除を指示
Note over B: Cookie を削除
Note over B,S: ログアウト後に再アクセス
B->>S: GET /mypage(Cookie なし)
S-->>B: 401 / ログインページへリダイレクト
Note over S: session_id がないため未認証として扱う
ログアウトのポイントは「2つ同時にやらないといけない」という点です
サーバー側でセッションを破棄するだけではブラウザにはまだ session_id が残っています
ブラウザの Cookie を消すためには、サーバーから Max-Age=0 を返して削除を指示する必要があります
:::message alert ログアウトには、サーバー側のセッション破棄とブラウザ側の Cookie 削除の両方が必要です。どちらか片方だけでは不完全なログアウトになります。 :::
3. 広告における Cookie¶
日常でよくある「さっき見ていた商品が別サイトでも広告に出る」という体験。これも Cookie で実現しています。
サードパーティ Cookie とは¶
Cookie には発行元によって 2 種類があります。
- ファーストパーティ Cookie:今見ているサイト自身(同じドメイン)が発行する Cookie。EC サイトのカートやログインがこれです。
- サードパーティ Cookie:今見ているサイトとは別のドメインが発行する Cookie。ページに埋め込まれた広告ネットワークなどが発行します。
サードパーティ Cookie の特徴は、ユーザーが直接そのサービスを訪問していなくても発行・送信される点です。これがサイトをまたいだ追跡を可能にします。
仕組み:サイト A での Cookie 発行¶
sequenceDiagram
participant B as ブラウザ
participant A as サイトA
participant Ad as ad-network
B->>A: 訪問
A-->>B: ページ(広告枠あり)
B->>Ad: 広告の読み込みリクエスト
Ad-->>B: 広告 + Set-Cookie: user=xxx
Note over B: ad-network の Cookie を保存
サイト A を見たとき、ページに広告枠が埋め込まれています。ブラウザは ad-network にも広告を取りに行くため、ad-network が Set-Cookie で user=xxx を発行します。ここが重要なポイントで、ユーザーは ad-network のサイトを自分で訪問したわけではないのに Cookie が保存されています。
仕組み:サイト B での追跡¶
sequenceDiagram
participant B as ブラウザ
participant Ad as ad-network
participant SB as サイトB
B->>SB: 訪問
SB-->>B: ページ(広告枠あり)
B->>Ad: 広告の読み込みリクエスト + Cookie: user=xxx
Note over Ad: サイトAもBも見た人と判明
Ad-->>B: サイトAで見た商品の広告
次にサイト B を訪問すると、そこにも同じ ad-network の広告枠があります。ブラウザは ad-network に広告を取りに行くとき、サイト A で保存した user=xxx を自動で送ります。ad-network は「この人はサイト A もサイト B も見た人だ」と分かるので、サイト A で見た商品の広告を返せます。これが「さっき見た商品が別サイトでも出る」の正体です。
広告で注目する Set-Cookie 属性¶
| 属性 | 例 | 役割 |
|---|---|---|
| Cookie 名と値 | ad_id=xyz |
ブラウザを継続して識別するための ID |
| クロスサイト制御 | SameSite=None |
クロスサイト文脈でも送るために必要 |
| HTTPS 限定 | Secure |
SameSite=None とセットで必要 |
| 有効期限 | Max-Age=2592000 |
日をまたいで同じ ID を使いやすくする |
EC サイトやログインでは SameSite=Lax / Strict で他サイトからの送信を制限しますが、広告はサイトをまたいで送る必要があるので SameSite=None にします。ただし SameSite=None は Secure とセットでないと使えません。
3rd パーティ Cookie の現在¶
この仕組み自体は攻撃ではなく広告配信の技術です。ただ、ユーザーが知らないうちにサイトをまたいで行動を追跡されることへの問題意識が高まり、ブラウザ各社が規制を強化しています。
| ブラウザ | 対応 |
|---|---|
| Safari | 2020年〜 全面ブロック(ITP) |
| Firefox | 2023年〜 デフォルトブロック(ETP) |
| Chrome | ユーザー選択制へ移行 |
参考 - Full Third-Party Cookie Blocking and More — WebKit Blog - Enhanced Tracking Protection in Firefox for desktop — Mozilla Support - Third-party cookies | Privacy Sandbox — Google
まとめ¶
- Cookie は、サーバーが
Set-Cookieでブラウザに保存させる小さなテキストデータ - ブラウザは次回以降、対応するリクエストでその Cookie を自動送信する
- Cookie 単体で設定や小さな手がかりを持てるし、Session ID と組み合わせればサーバー側の状態も引ける
- EC の未ログインカート、ログイン維持、広告はすべてこの発想の延長線上にある
- ログアウトではセッション破棄と Cookie 削除の両方が必要
Cookie の本質はひとつ、「サーバーがブラウザに渡すメモ」です。ブラウザはそのメモを自動で持参するので、ステートレスな HTTP でも「前回の続き」が実現できます。