文章

Cookie 机制详解

Cookie 机制详解

一句话概括

Cookie 不是存数据的,是 HTTP 无状态协议的身份补丁——每次请求自动带上,靠 HttpOnly + Secure + SameSite 三道防线保住安全的底线。

核心知识点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// —— 服务端设置(推荐方式)——
// Set-Cookie: sessionId=abc123; HttpOnly; Secure; SameSite=Lax; Max-Age=3600; Path=/

// —— 前端读写(只能操作非 HttpOnly 的)——
document.cookie = 'theme=dark; Max-Age=2592000; Path=/; Secure';
console.log(document.cookie); // "theme=dark; lang=zh"  ← 注意:返回字符串,不是对象

// 删除:设为过去时间
document.cookie = 'theme=; Max-Age=0; Path=/';

// 面试题:如何解析 document.cookie 为对象?
const parseCookie = str =>
  Object.fromEntries(str.split('; ').map(pair => pair.split('=')));
// { theme: 'dark', lang: 'zh' }
1
2
3
4
5
6
7
8
// 加 HttpOnly 的 Cookie,前端通过 document.cookie 拿不到
// Set-Cookie: sessionId=abc; HttpOnly; Secure

// 即使攻击者注入 <script>,也读不到 sessionId
console.log(document.cookie); // 不包含 sessionId

// 但正常请求照样带上:
// GET /api/user → Cookie: sessionId=abc

铁律: 凡是在服务端才用到的 Cookie(session id、csrf token),一律加 HttpOnly。前端需要读的才放 JS 可见区。

3. SameSite — Chrome 80+ 最大行为变化

1
2
3
4
5
6
7
8
9
10
11
12
// Strict: 严格,任何跨站都不带
// 场景:从邮件点链接进银行 → 需要重新登录
Set-Cookie: id=xxx; SameSite=Strict

// Lax: Chrome 默认(80+),允许安全的跨站导航带 Cookie
// ✅ <a> 点击跳转 → 带
// ✅ 顶层 GET 表单提交 → 带
// ❌ <img> / iframe / AJAX 跨站请求 → 不带
Set-Cookie: id=xxx; SameSite=Lax

// None: 完全放开,必须搭配 Secure(即 HTTPS)
Set-Cookie: tracking=xxx; SameSite=None; Secure

面试重点: Chrome 80 将默认值从 None 改为 Lax,很多第三方登录、iframe 内嵌应用突然失效,就是没设 SameSite=None; Secure

4. Domain 与 Path — 控制可见边界

1
2
3
4
5
6
7
8
9
10
11
// 不设 Domain → 仅当前域名(不含子域名)
// 设在 www.example.com,api.example.com 看不到
Set-Cookie: token=xxx; Path=/admin

// 设 Domain=.example.com → 所有子域名共享
// api.example.com、admin.example.com 都能读到
Set-Cookie: lang=zh; Domain=.example.com

// Path 限定 URL 路径前缀
Set-Cookie: adminToken=xxx; Path=/admin
// 只有 /admin 及子路径生效
 CookielocalStorage
会自动发请求
HttpOnly 防 XSS
SameSite 防 CSRF
容量4KB5-10MB
性能带了太多会拖慢每个请求不影响网络
过期控制✅ 原生❌ 需手动封装

其实你每天都在用

  • 登录态维持sessionId 放 HttpOnly Cookie,每次请求自动带,服务器就知道你是谁
  • 勾选”两周内免登录”:后端设 Max-Age=1209600,两周内自动登录
  • 第三方广告追踪:A 网站嵌入的 B 站 iframe 用 SameSite=None 的 Cookie 追踪你的浏览行为
  • 多语言偏好lang=zh-CN 存 Cookie,后端直接渲染对应语言的页面,无需前端二次切换
  • CSRF 防御:后端下发的 csrf token 存 Cookie(不设 HttpOnly),前端读取后放进请求头

常见误解

  • ❌ 误区:「Cookie 就 4KB,太废物了」 Cookie 的定位从来不是 Storage 而是 Transport——它的核心价值是”每次请求自动带”。把大数据放在 Cookie 里的人不是 Cookie 的问题,是不会用 localStorage。

  • ❌ 误区:「设了 HttpOnly 就安全了」 HttpOnly 只防 XSS 窃取,管不了中间人攻击(需要 Secure),也管不了 CSRF(需要 SameSite 或 CSRF Token)。三道防线是 AND 关系,不是 OR。

  • ❌ 误区:「SameSite=Lax 替代了 CSRF Token」 Lax 解决了跨站 POST/PUT/DELETE 的 CSRF,但 GET 请求的 CSRF 仍可能有问题——比如某些老接口用 GET 做删除操作。CSRF Token 依然是纵深防御的必要组件。

  • ❌ 误区:「前端设 Cookie 和后端设一样」 不一样。document.cookie 无法设置 HttpOnly,这意味着前端写入的任何 Cookie 都能被 JS 读取。真正需要保密的(session id)必须由后端 Set-Cookie 响应头下发。

一句话总结

Cookie 三板斧:HttpOnly 让脚本看不见,Secure 让中间人截不到,SameSite=Lax 让跨站请求带不走——三者缺一不可。

本文由作者按照 CC BY 4.0 进行授权

© 独行的风. 保留部分权利。

本站采用 Jekyll 主题 Chirpy

本站总访问量 本站访客数 本文阅读量