一覧へ

クッキーとは何か — HTTPの状態管理

HTTPクッキーが必要な理由、その仕組み、セキュリティプロパティについて、Expressの例を通して学びます。

中級
|
10
|
検証済み (2026-07)
クッキーHTTP状態管理Set-Cookieセッション認証
進捗0/55 (0%)

クッキーとは? — HTTPの状態管理

このトピックを完了すると、以下のことができるようになります。

HTTPが「ステートレス」なプロトコルである理由を理解し、クッキーがどのようにこの問題を解決するかを説明し、Expressでクッキーを設定および読み取る方法を理解します。


HTTPにはメモリがない

HTTPプロトコルはステートレスです。リクエストを処理した後、サーバーはクライアントを完全に忘れてしまいます。

text
クライアント: GET /page1 → サーバー: "Page 1の内容はこちらです"
クライアント: GET /page2 → サーバー: "あなたは誰ですか?はじめまして。Page 2の内容はこちらです"

サーバーは、1秒前に/page1をリクエストしたブラウザが、同じユーザーであるかどうかを判断できません。「過去のリクエストを記憶する」ような機能(ログイン、ショッピングカート、ダークモード設定など)は、このステートレスな性質のために不可能です。

クッキーは、この問題を解決します。これは、サーバーがクライアントに「この情報を保存し、次回アクセスしたときに私に見せてください」と言うようなものです。


クッキーの仕組み

クッキーはHTTPヘッダーを通じて交換されます。

text
1. サーバー → クライアント(レスポンスヘッダー)
   Set-Cookie: username=Hoon; Path=/

2. クライアント → サーバー(次のリクエストのリクエストヘッダー)
   Cookie: username=Hoon

設定されると、ブラウザはクッキーを同じドメインへのすべてのリクエストに自動的に含めます。サーバーが要求しなくても、ブラウザはそれを送信します。これがクッキーの基本的な仕組みです。


Expressでのクッキーの処理

クッキーの設定

javascript
const express = require('express');
const app = express();

app.get('/login', (req, res) => {
  // Set-Cookieヘッダーを送信
  res.cookie('username', 'Hoon', {
    maxAge: 24 * 60 * 60 * 1000, // 1日(ミリ秒)
    httpOnly: true,
    secure: false,    // HTTPS経由でのみ送信(開発中はfalseに設定)
    sameSite: 'lax'
  });
  res.json({ message: 'ログインしました。クッキーを設定しました' });
});

クッキーの読み取り

クッキーを読み取るには、cookie-parserミドルウェアが必要です。

bash
npm install cookie-parser
javascript
const cookieParser = require('cookie-parser');
app.use(cookieParser());

app.get('/profile', (req, res) => {
  const username = req.cookies.username;
  if (!username) {
    return res.status(401).json({ error: 'ログインしていません' });
  }
  res.json({ message: `ようこそ、${username}さん` });
});

cookie-parserは、Cookieヘッダーを解析し、req.cookiesオブジェクトを作成します。このミドルウェアがない場合、ヘッダーを自分で解析する必要があります。

クッキーの削除

javascript
app.get('/logout', (req, res) => {
  res.clearCookie('username');
  res.json({ message: 'ログアウトしました。クッキーをクリアしました' });
});

clearCookieは、同じ名前のクッキーをすぐに期限切れにします。


クッキー属性

属性説明
maxAge生存期間(ミリ秒)。この時間が経過すると、クッキーは自動的に削除されます86400000(1日)
expires期限切れの日付(Dateオブジェクト)。maxAgeよりも一般的に使用されませんnew Date('2026-12-31')
httpOnlyJavaScriptからアクセスできません(XSS対策の鍵)true
secureHTTPS接続でのみ送信されますtrue
sameSite他のサイトからのリクエストにクッキーを含めるかどうか'strict', 'lax', 'none'
pathこのパス以下のパスに対してのみ、クッキーが送信されます'/'
domainクッキーが有効なドメイン'.example.com'

これらの属性の中で、httpOnlysecureはセキュリティにとって最も重要です。


セキュリティ — クッキーを安全に保つ

httpOnly

javascript
// 悪い — クッキーはJavaScriptからアクセスできます(XSS脆弱性)
res.cookie('token', 'abc123');

// 良い — JavaScriptからアクセスできません
res.cookie('token', 'abc123', { httpOnly: true });

httpOnly: trueを設定すると、document.cookieを使用してクッキーを読み取ることができなくなります。XSS攻撃者がスクリプトを挿入しても、クッキーを盗むことはできません。これは、認証関連のクッキーには常に設定する必要があります。

secure

javascript
res.cookie('token', 'abc123', {
  httpOnly: true,
  secure: true  // HTTPS経由でのみ送信
});

クッキーは、HTTP(暗号化されていない)接続経由で送信されません。攻撃者はクッキーを傍受できません。

sameSite

javascript
res.cookie('token', 'abc123', {
  httpOnly: true,
  secure: true,
  sameSite: 'strict'  // 同じサイトからのリクエストでのみ送信
});
動作
'strict'クッキーは、同じサイトからのリクエストにのみ含まれます。完全にCSRFをブロックします。ただし、ユーザーが外部リンクからサイトにアクセスすると、ログアウトします。
'lax'GETリクエスト(リンクのクリック)は許可しますが、POSTリクエストはブロックします。CSRF保護と使いやすさの妥協点です。推奨。
'none'すべてのリクエストに含まれます。secure: trueが必要です。クロスサイトAPIでのみ使用されます。

クッキーとlocalStorage

クッキーlocalStorage
サーバーに送信されるすべてのリクエストに自動的に含まれる送信されない
サイズ約4KB約5MB
有効期限自動的に期限切れになる手動で削除されるまで
アクセスhttpOnlyが設定されている場合、JavaScriptからアクセスできませんJavaScriptからのみアクセス可能
使用例認証、セッション、サーバー設定UIの状態、キャッシュ、オフラインデータ

「サーバーが知っておく必要のある情報」にはクッキーを使用し、「ブラウザのみが知っておく必要のある情報」にはlocalStorageを使用します。


実際のパターン — ダークモードクッキー

javascript
// ダークモードの設定 — サーバーサイドレンダリング中に適用できます
app.post('/settings/theme', (req, res) => {
  const { theme } = req.body; // 'dark'または'light'
  res.cookie('theme', theme, {
    maxAge: 365 * 24 * 60 * 60 * 1000, // 1年
    httpOnly: false,  // CSSを適用するにはJavaScriptアクセスが必要です
    sameSite: 'lax'
  });
  res.json({ theme });
});

app.get('/', (req, res) => {
  const theme = req.cookies.theme || 'light';
  res.render('index', { theme });
});

ダークモードなどのセキュリティに敏感でない設定では、httpOnly: falseを設定できます。ただし、認証トークンにはhttpOnly: falseを設定しないでください。


主要なポイント

概念概要
HTTPステートレスサーバーは過去のリクエストを記憶しません
クッキーサーバーがクライアントに保存するように要求する小さなデータ
Set-Cookieサーバー → クライアント(レスポンスヘッダー)
Cookieクライアント → サーバー(リクエストヘッダー、自動)
httpOnlyJavaScriptからのアクセスを防止します(XSS対策)
secureHTTPS経由でのみ送信されます
sameSiteCSRF保護(laxを推奨)

クッキーは、Webにおける最も古い状態管理メカニズムの1つですが、現在でも広く使用されています。セッション、認証、ユーザー設定など、これらはすべてクッキーに基づいています。セキュリティ属性(httpOnlysecuresameSite)を設定し忘れると、XSSおよびCSRF攻撃に対して脆弱になるため、クッキーを設定する際には、常にこれら3つを確認してください。


本番環境チェックリスト

認証クッキーを設定する場合は、次の項目を確認してください。

javascript
res.cookie('session_token', token, {
  httpOnly: true,       // ✓ XSS対策 — JavaScriptからのアクセスを防止
  secure: true,         // ✓ HTTPSのみ — 暗号化されていないテキストでの送信を防止
  sameSite: 'lax',      // ✓ CSRF対策 — クロスサイトPOSTリクエストをブロック
  maxAge: 3600000,      // ✓ 有効期限を設定 — 永続的なクッキーを防止
  path: '/'             // ✓ パスを制限 — 必要な範囲に制限
});

これらのいずれかを忘れると、セキュリティ上の脆弱性が生じます。本番環境にデプロイする前に、このチェックリストを確認してください。

💬 質問・コメント

0件のコメント

ログインせずに投稿できます。ゲスト投稿は投稿者自身で編集・削除できません。

0/2000

読み込み中...