はじめに
「ログインしたのに、別のページに移動したらまたログイン画面が出る」
そんな経験はさすがにないと思いますが、実はHTTPの仕組み上、何も対策しなければ本当にそうなります。
なぜなら、HTTPは ステートレス(状態を持たない) なプロトコルだからです。
この記事では、ステートレスなHTTPに「状態」を持たせる3つの仕組み ― Cookie・Session・JWT の違いを図解で解説します。
この記事は 「図解でわかるWeb技術の仕組み」シリーズ の第2回です。
第1回:HTTPリクエスト/レスポンスの仕組みを先に読むと、よりスムーズに理解できます。
1. なぜ「状態管理」が必要なのか
HTTPはステートレス
まずは、HTTPの根本的な特徴を押さえましょう。
HTTPでは、1回のリクエスト/レスポンスが完結したら、その会話は終わりです。サーバーは「さっきログインしたTaroさん」という情報を一切覚えていません。
これが ステートレス(stateless) の意味です。
ステートレスのメリットとデメリット
| 内容 | |
|---|---|
| メリット | サーバーの設計がシンプル。スケールアウト(サーバーを増やす)しやすい |
| デメリット | そのままではログイン状態やカートの中身を保持できない |
ステートレス自体は悪いことではありません。むしろHTTPが世界中で使われている理由の1つです。ただし、認証やカート機能を実現するには「状態を持たせる仕組み」が別途必要 になります。
それが Cookie・Session・JWT です。
2. Cookie ― ブラウザに「名札」を持たせる
Cookieとは
Cookie とは、サーバーがブラウザに渡す 小さなデータ(Key=Valueの文字列) です。ブラウザはCookieを保存し、次回以降のリクエストで自動的にサーバーに送り返します。
Cookieの仕組み
ポイントは 「ブラウザが自動で送る」 ということ。開発者が毎回手動でCookieを付ける必要はありません。
Cookieのヘッダー
# サーバー → ブラウザ(Cookieを発行)
Set-Cookie: session_id=abc123; Path=/; HttpOnly; Secure; SameSite=Lax
# ブラウザ → サーバー(次回から自動送信)
Cookie: session_id=abc123
Cookieの主な属性
| 属性 | 意味 | 例 |
|---|---|---|
Path |
Cookieを送るパスの範囲 |
Path=/ (サイト全体) |
Domain |
Cookieを送るドメイン | Domain=example.com |
Expires / Max-Age
|
有効期限 |
Max-Age=3600(1時間) |
HttpOnly |
JavaScriptからアクセス不可 | XSS対策 |
Secure |
HTTPS通信でのみ送信 | 盗聴防止 |
SameSite |
クロスサイトリクエストの制御 | CSRF対策 |
セキュリティ上の必須設定
認証に関わるCookieには、必ず HttpOnly、Secure、SameSite を設定しましょう。これらを省略すると、XSSやCSRF攻撃のリスクが高まります。
3. Session ― サーバー側で状態を管理する
Sessionとは
Session(セッション) とは、ユーザーごとの状態を サーバー側で保持する仕組み です。
ブラウザには セッションID(ただの識別子)だけを渡し、実際のデータはサーバーが持ちます。
Sessionの仕組み
Cookie と Session の関係
ここが混同しやすいポイントです。
Cookie = データの「運び方」(配送手段)
Session = データの「管理方法」(保管場所はサーバー)
つまり、Session はCookieを使ってセッションIDを運ぶ のが一般的です。2つは対立する概念ではなく、組み合わせて使います。
ブラウザ ──── Cookie(session_id=abc123)────→ サーバー
↓
セッションストアで
abc123 → Taroさん と検索
Sessionのメリット・デメリット
| 内容 | |
|---|---|
| メリット | データがサーバー側にあるので安全。即座にセッションを無効化できる |
| デメリット | サーバーに負荷がかかる。複数サーバー構成ではセッション共有が必要(Redis等) |
4. JWT ― トークンに情報を埋め込む
JWTとは
JWT(JSON Web Token、ジョット) は、ユーザー情報を トークン(文字列)自体に埋め込む 方式です。
Sessionがサーバーにデータを保存するのに対し、JWTは サーバーにデータを保存しません。
JWTの構造と仕組み
JWTは 3つのパーツ をドット(.)でつないだ文字列です。
| パーツ | 内容 | 役割 |
|---|---|---|
| Header | アルゴリズム・トークン種別 | 「どうやって署名したか」 |
| Payload | ユーザー情報(claims) | 「誰の、どんなデータか」 |
| Signature | 署名 | 「改ざんされていないか検証」 |
実際のJWTはこのような文字列です(Base64エンコード済み):
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJ1c2VyX2lkIjoxLCJuYW1lIjoiVGFybyJ9.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
なぜサーバーに保存しなくて良いのか
JWTの最大の特徴は 「署名(Signature)」 です。
Signature = HMACSHA256(Header + "." + Payload, 秘密鍵)
サーバーは秘密鍵を持っているので、受け取ったJWTの署名を 再計算して照合 できます。一致すれば「自分が発行した、改ざんされていないトークン」だと確認できます。
JWTのPayloadは暗号化されていない
Base64は「エンコード」であり「暗号化」ではありません。誰でもデコードして中身を読めます。パスワードなどの機密情報は絶対にPayloadに入れないでください。
JWTのメリット・デメリット
| 内容 | |
|---|---|
| メリット | サーバーに状態を持たないのでスケールしやすい。モバイルアプリとも相性が良い |
| デメリット | 発行済みトークンの即時無効化が難しい(有効期限まで有効)。トークンサイズが大きい |
5. Cookie・Session・JWT の比較
3つの違いを一覧で整理します。
一番大きな違い ― 「状態をどこに持つか」
Cookie → ブラウザに持つ(ただしKey=Valueの小さなデータだけ)
Session → サーバーに持つ(ブラウザにはIDだけ渡す)
JWT → ブラウザに持つ(トークン自体にユーザー情報を含む)
6. どれを使うべき?
「結局どれを使えばいいの?」という疑問に、ユースケース別で答えます。
判断フローチャート
認証が必要?
├── No → Cookie(設定保存程度なら十分)
└── Yes
├── サーバーサイドレンダリング?(Rails, Django, Laravel等)
│ └── Session
└── SPA or モバイルアプリ?(React, Vue, iOS, Android等)
└── JWT
実務では組み合わせることが多い
例えば「JWTをHttpOnly Cookieに格納する」パターンは、JWTのスケーラビリティとCookieのセキュリティ属性を両立できるため、実務でよく使われます。
7. セキュリティ上の注意点
認証に関わる仕組みだからこそ、セキュリティは重要です。
Cookie / Session を使う場合
| 脅威 | 対策 |
|---|---|
| XSS(Cookie の窃取) |
HttpOnly 属性を設定する |
| CSRF(なりすましリクエスト) |
SameSite 属性 + CSRFトークンを使う |
| 盗聴 |
Secure 属性で HTTPS 通信に限定する |
JWT を使う場合
| 脅威 | 対策 |
|---|---|
| トークン漏洩 | HttpOnly Cookie に格納する / localStorage に入れない |
| 無効化できない | 有効期限を短くする(15分〜1時間) + リフレッシュトークンを併用する |
| 改ざん | 署名アルゴリズムを none にしない / 秘密鍵を厳重に管理する |
8. まとめ
| 項目 | ポイント |
|---|---|
| HTTPの特性 | ステートレス(各リクエストは独立、前後の関係を持たない) |
| Cookie | ブラウザにKey=Valueを保存。自動で送信される「名札」 |
| Session | サーバー側で状態を保持。ブラウザにはセッションIDだけ渡す |
| JWT | トークン自体にユーザー情報を埋め込む。サーバーに状態を持たない |
| 使い分け | 従来型Webアプリ → Session / SPA・モバイル → JWT |
次回予告
第3回では 「OAuth 2.0 の仕組み」 を図解で解説します。「Googleでログイン」「GitHubでログイン」の裏側で何が起きているのか — 認可コードフロー を一歩ずつたどります。
シリーズ目次
| # | テーマ |
|---|---|
| 1 | HTTPリクエスト/レスポンスの仕組み |
| 2 | Cookie・Session・JWTの違い(この記事) |
| 3 | OAuth 2.0 の仕組み |
| 4 | DNS解決の流れ |
| 5 | HTTPS・TLS通信の仕組み |
| 6 | CDN の仕組みと役割 |
| 7 | WebSocket ― 双方向リアルタイム通信 |
| 8 | キャッシュ戦略(ブラウザ・サーバー・CDN) |
| 9 | CORS ― クロスオリジンの壁を理解する |
| 10 | REST API 設計の基本原則 |
「この記事が役に立った」と思ったら、LGTM とストックをお願いします。
@kotaro_ai_lab
AI活用や開発効率化について発信しています。フォローお気軽にどうぞ!





