- 后端
- 文档
- 教程
【免费下载链接】system-design-101
Explain complex systems using visuals and simple terms. Help you prepare for system design interviews.
HTTP 是万维网的"语言",天生无状态,服务器无法记住上一次请求你是谁;而 Cookie 正是为这一缺陷补位的"会话秘方"——它让浏览器替用户保管一张写有身份与偏好信息的小纸条,在后续每次请求中自动递给服务器,从而支撑起登录态、购物车、个性化推荐等无缝的连续浏览体验。读完本文,你将掌握 Cookie 的完整生命周期(服务器下发、浏览器存储、随请求回传)、浏览器为何是"Cookie 守门人",以及 SameSite、Secure、HttpOnly、Domain 等核心属性的取舍之道,可直接用于日常 Web 开发与系统设计面试答题。
为什么需要 Cookie:HTTP 的"金鱼记忆"
HTTP 协议天然是stateless(无状态)的:每一次请求都是独立的、孤立的,协议层面不携带任何关于"上一次交互"的记忆。正如 http-cookies-explained-with-a-simple-diagram.md 开篇所描述的那样——HTTP 像一条金鱼,瞬间就会把你忘记。
但现代 Web 应用恰恰依赖"连续体验":登录后访问页面、往购物车加商品、保持语言偏好……这些场景都需要服务器在多次请求之间记住同一个用户。如果没有任何机制,用户每点击一次页面都要重新登录,体验将无法忍受。
Cookie 正是为此而生:它是"会话秘方",把无状态的 HTTP 请求串联成有状态的用户会话。
Cookie 是什么:写给服务器的小纸条
可以把 Cookie 理解为你递给 Web 服务器的小纸条,上面写着:"请记住我。" 这张纸条由服务器生成、随响应下发,最终**存储在浏览器(客户端)**一侧,而不是服务器上。
仓库中的姊妹篇 what-is-a-cookie.md 给出了一个更直观的比喻:
想象 Bob 第一次走进咖啡馆,点了一杯中杯、加两份糖的浓缩咖啡。收银员把 Bob 的身份和口味偏好记在一张卡片上,随咖啡一起交还给他。下次 Bob 再来,只需出示这张卡片,收银员立刻知道他是谁、喜欢什么。
Cookie 就是这张"偏好卡":
- 用户登录网站时,服务器签发一小份数据作为 Cookie;
- Cookie 存储在客户端;
- 下一次请求时,浏览器自动带上 Cookie;
- 服务器看到 Cookie,立刻识别用户身份与偏好,无需再查数据库。
这个"免查库即识别"的特性,让 Cookie 在提升体验的同时也降低了服务端的查询压力。
Cookie 的完整工作流程
一次典型的 Cookie 会话包含以下步骤(结合 what's-the-difference-between-session-based-authentication-and-jwts.md 中 Session 认证的流程梳理):
- 用户通过前端应用发起登录请求,请求到达后端服务器;
- 后端校验凭据后创建会话(Session),把会话数据写入会话存储(session store),并生成唯一的 Session ID;
- 服务器在响应中通过
Set-Cookie响应头把 Session ID 下发给浏览器; - 浏览器收到后把该 Cookie 保存在本地;
- 用户发起下一次请求时,浏览器自动在请求头
Cookie中带上这个 Session ID; - 服务器凭 Session ID 从会话存储中取回用户信息,完成身份识别与授权。
从协议层面看,核心就两个头:
| 方向 | 头部 | 作用 |
|---|---|---|
| 服务器 → 浏览器 | Set-Cookie | 指示浏览器保存一个 Cookie 及其属性 |
| 浏览器 → 服务器 | Cookie | 携带此前保存的、符合发送条件的 Cookie |
一个典型的Set-Cookie响应头形如:
Set-Cookie: sessionId=abc123xyz; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=86400之后浏览器自动回传:
Cookie: sessionId=abc123xyz需要注意:Cookie 默认随每个符合条件的后续请求自动发送(详见 what-are-the-differences-between-cookies-and-sessions.md),这意味着开发者无需手动管理传输逻辑,但也要为此承担"每次请求都携带"的带宽与隐私成本。
浏览器:Cookie 的守门人
为什么浏览器会被称作 "Cookie 守门人(cookie bouncer)"?因为浏览器有一套严格的同源(Same-Origin)判定与发送规则,防止你的 Cookie 被"投递"到错误的网站。
浏览器不会把a.com的 Cookie 主动发送给b.com。Cookie 是否随请求发送,由以下因素共同决定:
- Domain 属性:声明该 Cookie 归属哪个域名(可含子域),浏览器只把 Cookie 发送给匹配域名的请求;
- Path 属性:进一步限定 Cookie 只对该路径及其子路径生效;
- Secure 属性:要求 Cookie 仅在 HTTPS 连接下发送;
- SameSite 属性:控制跨站请求(Cross-Site)时是否携带 Cookie,是近年防 CSRF(跨站请求伪造)的关键开关。
这套"守门"机制确保了 A 网站设置的 Cookie 不会"串台"到 B 网站,从协议层遏制了最基本的身份冒用风险。
Cookie 的核心属性:撑起 Cookie 罐的明星成员
原文档点名的五位"明星成员"——SameSite、Name、Value、Secure、Domain,外加实践中同样关键的HttpOnly、Path、Expires/Max-Age,共同构成一份完整 Cookie 的全部规则:
| 属性 | 作用 | 说明与建议 |
|---|---|---|
Name | Cookie 的名字 | 与Value组成键值对;同一域名下以Name=Value整体识别 |
Value | Cookie 的值 | 保存 Session ID、偏好标记等小份数据;不要存放敏感明文 |
Domain | 限定生效域名 | 指定该 Cookie 属于哪个站点;不指定时默认仅当前主机,指定后子域也可共享 |
Path | 限定生效路径 | 默认/,即全站生效;可缩窄到/admin等特定目录以缩小暴露面 |
Secure | 仅 HTTPS 传输 | 保证 Cookie 不在明文 HTTP 中传输,防中间人窃听;生产环境应开启 |
HttpOnly | 禁止 JS 读取 | 使document.cookie无法访问该 Cookie,从根源上缓解 XSS 窃取会话的风险;会话类 Cookie 必须开启 |
SameSite | 跨站发送策略 | 取值Strict(完全禁止跨站携带)/Lax(仅顶层导航等安全场景携带)/None(允许跨站携带,须配Secure) |
Expires/Max-Age | 有效期 | 决定 Cookie 是"会话级"(关浏览器即失效)还是"持久级"(存到指定过期时间);Max-Age优先于Expires |
SameSite 详解
SameSite是防 CSRF 的重要防线,取值差异直接影响安全等级:
Strict:最严格,任何跨站请求都不携带 Cookie,安全但可能影响从外链正常访问时的登录态;Lax(现代浏览器默认):允许在用户点击链接、地址栏输入等"顶层导航"场景携带 Cookie,平衡安全与体验;None:允许第三方场景携带,必须同时设置Secure(HTTPS),常用于跨站单点登录等场景,也是第三方 Cookie 争议的焦点。
HttpOnly 与 XSS 的关系
HttpOnly是防御 XSS(跨站脚本攻击)偷取会话的关键属性。攻击者即使注入了脚本,也无法通过document.cookie读取标记了HttpOnly的会话 Cookie,从而无法冒充用户身份。因此,承载 Session ID 的 Cookie 应当始终开启HttpOnly。
有效期与第三方 Cookie
- 会话级 Cookie(无
Expires/Max-Age)存在内存中,浏览器关闭即清除; - 持久级 Cookie 存到磁盘,按过期时间存活;
- 在现代浏览器中,第三方 Cookie(由当前页面之外的其他域名设置的 Cookie)越来越多地被默认拦截,这直接影响广告追踪、跨站登录等场景,是系统设计时需要纳入考量的环境约束。
从 Cookie 到会话:Cookie 与 Session 的分工
Cookie 常与 Session 成对出现,二者是"分工合作"的关系(详见 what-are-the-differences-between-cookies-and-sessions.md 与 cookies-vs-sessions-vs-jwt-vs-paseto.md):
| 维度 | Cookie | Session |
|---|---|---|
| 存储位置 | 客户端(浏览器) | 服务端(会话存储 / 数据库) |
| 数据容量 | 通常有 4KB 左右的体积限制,只适合小份数据 | 可承载更大体量的数据 |
| 传输方式 | 随每个后续请求自动发送 | 由 Cookie 携带的 Session ID 引用,数据不直接传输 |
| 安全性 | 数据暴露在客户端,可被用户查看/篡改 | 数据不直接暴露给客户端,相对更安全 |
| 控制权 | 用户可在浏览器中禁用 Cookie | 服务端可精确控制会话生命周期 |
| 扩展性 | —— | 在分布式系统中,会话存储需要同步或集中化,面临扩展挑战 |
关键结论:Cookie 负责"携带凭证",Session 负责"保存数据"。服务端把大数据量的用户状态放进 Session,只在 Cookie 里放一个轻量 Session ID,既绕开了 Cookie 的体积限制,又避免敏感数据直接暴露给客户端。
Cookie 在认证体系中的位置:与 JWT、Token 的对比
在用户身份管理演进谱系中,Cookie 是基础而重要的角色(可参考 token-cookie-session.md 与 session-cookie-jwt-token-sso-and-oauth-2.md):
- WWW-Authenticate:最原始的账号密码认证,无法控制登录生命周期,如今已很少使用;
- Session-Cookie:服务端维护会话存储、浏览器保存 Session ID 的方案,对登录生命周期有精细控制,但 Cookie 天然只适合浏览器场景,对移动 App 不友好;
- Token:把身份信息编码进令牌、由客户端保存并回传,解决跨端兼容问题,但需要加解密,有一定开销;
- JWT:将令牌标准化,利用数字签名保证可信,签名内嵌于令牌本身,服务端无需保存会话(详见 what's-the-difference-between-session-based-authentication-and-jwts.md);
- SSO / OAuth 2.0:在 Cookie 与 Token 之上构建跨站点身份联合与授权体系。
对比要点(依据 cookies-vs-sessions-vs-jwt-vs-paseto.md):
- Session + Cookie:服务端对数据有强控制权,但分布式系统中会话存储扩展较困难;
- JWT:无状态、自包含、天然可扩展,但需要防范令牌被盗,并妥善管理过期时间;
- PASETO:作为 JWT 的改进方案,强制更强的密码学默认配置,从设计上消除算法混淆类漏洞。
值得注意的是:JWT 最终也常常通过 Cookie 方式下发给浏览器(见 what's-the-difference-between-session-based-authentication-and-jwts.md 所述"cookie approach")。也就是说,无论底层是 Session 还是 JWT,Cookie 都是浏览器端承载凭证的标准载体——这也解释了为什么理解 Cookie 是理解整个认证体系的前提。
安全实践清单
综合上述机制,生产环境下的 Cookie 配置应遵循以下基线:
- 会话凭证 Cookie 必须设置
HttpOnly,阻断 XSS 窃取; - 必须设置
Secure,只允许 HTTPS 传输; SameSite至少设置为Lax,非必要不放开到None;- 使用
Domain与Path将 Cookie 作用域收窄到最小必要范围; - 敏感信息不写入 Cookie
Value,只存放 Session ID 这类"引用型"凭证; - 为持久 Cookie 设置合理的
Max-Age,避免长期滞留客户端; - 在分布式架构中,若采用 Session 方案,需为会话存储设计集中化或共享方案,并警惕扩展瓶颈。
小结
Cookie 以"客户端小纸条"的形态,为无状态的 HTTP 注入了会话能力;浏览器则以同源规则充当守门人,控制 Cookie 的发送边界;而Name/Value、Domain、Path、Secure、HttpOnly、SameSite、Expires/Max-Age这些属性共同定义了 Cookie 的存取规则与安全边界。理解 Cookie 的机制,是理解 Session、JWT、SSO、OAuth 2.0 等整个身份认证演进体系的基础——无论你在做 Web 开发还是备战系统设计面试,这都是必须掌握的第一块拼图。
如需继续深入,可在本仓库中按序阅读 what-is-a-cookie.md(Cookie 的基本概念)、what-are-the-differences-between-cookies-and-sessions.md(Cookie 与 Session 对比)、cookies-vs-sessions-vs-jwt-vs-paseto.md(四种认证方案对比)与 session-cookie-jwt-token-sso-and-oauth-2.md(身份管理演进全景)。
- 后端
- 文档
- 教程
【免费下载链接】system-design-101
Explain complex systems using visuals and simple terms. Help you prepare for system design interviews.
相关推荐
system-design-101 之 JWT 101:无状态认证的核心密钥
system design 101 之 JWT 101:无状态认证的核心密钥 JWT(JSON Web Token)是用于在双方之间安全传输信息的开放标准,也是
后端文档教程FuzzySharp核心功能解析:7种字符串相似度算法对比与实战
FuzzySharp核心功能解析:7种字符串相似度算法对比与实战 FuzzySharp是C .NET平台上的模糊字符串匹配库,基于著名的Python Fuzzy
后端libsignal协议状态机:会话状态的持久化与恢复
libsignal协议状态机:会话状态的持久化与恢复 概述 在Signal的端到端加密通信中,会话状态管理是确保消息安全传输的核心机制。libsignal协议通
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考