3秒でわかる
サーバーがブラウザに預け、次のリクエストで自動的に返してもらう小さなデータ。状態を持てない HTTP でログイン状態を保つために使います。
30秒図解
もう少し詳しく
どういうものか
Cookie は、サーバーがブラウザに預けておく小さな文字列です。サーバーは応答に Set-Cookie というヘッダを付けて渡し、ブラウザは同じサイトへの次のリクエストで、そのデータを Cookie ヘッダに入れて自動的に送り返します。この往復により、サーバーは「さっきのリクエストと同じ人だ」と判断できます。
保存できる大きさはひとつあたり 4KB 程度で、有効期限、送る対象のドメインとパス、付随する属性を一緒に指定できます。
なぜ必要か
HTTP は 1 回のやり取りが終わると相手を忘れる仕組みです。何もしなければ、ログイン画面で認証した直後に次のページを開いた時点で、サーバーからは初対面の相手に見えます。Cookie に発行済みのセッション識別子を持たせることで、ページをまたいでも同じ利用者として扱えるようになります。買い物かごの中身や表示言語の設定も、同じ考え方で保持されます。
具体例
サーバーが発行する側の書き方です。安全に関わる属性を付けています。
res.setHeader(
"Set-Cookie",
"sid=abc123; HttpOnly; Secure; SameSite=Lax; Max-Age=3600; Path=/"
);属性の意味は下のとおりです。
| 属性 | 効果 |
|---|---|
| HttpOnly | JavaScript から読めなくする |
| Secure | HTTPS のときだけ送る |
| SameSite | 他サイト経由の送信を制限する |
| Max-Age | 秒数で有効期限を決める |
つまずきやすいところ
セッション識別子を HttpOnly なしで発行すると、ページに紛れ込んだ悪意あるスクリプトから document.cookie で読み出され、そのままなりすましに使われます。認証に関わる Cookie では HttpOnly と Secure を省かないでください。
もうひとつ、Cookie に利用者の名前や権限を直接書き込む設計は危険です。ブラウザ側で自由に書き換えられるため、role=admin と書き換えられれば管理者になれてしまいます。Cookie に入れるのは推測できない識別子だけにし、中身はサーバー側で持ちます。
開発中にログイン状態が保てない場合、SameSite の指定と、http と https の食い違いを先に疑うと早く解決します。
似た用語との違い
localStorage も情報をブラウザに残しますが、リクエストのたびに自動で送られることはなく、JavaScript から読み書きします。サーバーに毎回届けたい情報は Cookie、ブラウザの中だけで使う情報は localStorage という切り分けが基本です。