Cookie 是什么
Cookie 是浏览器自动附加到请求上的状态字段:服务端之前写入的所有作用域内状态,会以「名值对用分号分隔」的形式出现在同一个请求头里。它是无状态协议维持会话的标准手段,也因此被滥用——体积过大、作用域过宽、敏感数据明文存放,都会带来性能与安全问题。理解它要抓住三个点:浏览器按作用域自动发送、总体积有限制、服务端无法控制客户端发送顺序。
基本信息
| 名称 | Cookie(RFC 6265 §5.4) |
|---|---|
| 作用 | 携带服务端之前写入的状态 |
| 发送规则 | 浏览器按路径与域的作用域自动附加 |
| 体积限制 | 单个状态项约数十字节级上限,同一域名的项数也有限 |
| 顺序 | 按路径长度排序发送,服务端不能假定固定顺序 |
典型使用场景
- 会话保持:登录后在每个请求上携带会话标识
- 个性化偏好:主题、语言、时区等不影响安全的设置
- 埋点与实验分流:把分组标识写在客户端以便后端识别
- 跨页面的流程状态:多步表单中暂存已完成的步骤
- 风险识别:把设备指纹类信息写入并在后续请求中校验
查看与手工携带
查看与手工携带
curl -si https://www.example.com/ | grep -i '^set-cookie' # 先看服务端写了哪些状态
curl -si https://www.example.com/me -H 'Cookie: sessionid=abc123; theme=dark' # 手工携带,验证服务端行为
# 浏览器开发者工具的存储面板里能看到每个状态的属性与实际作用范围读请求时要关注什么
| 关注点 | 原因 |
|---|---|
| 是否有重复的名字 | 同一名字可能有多份,取值结果取决于服务端实现 |
| 体积是否偏大 | 每次请求都会带上,直接影响所有请求的耗时 |
| 是否包含敏感数据 | 明文存放在客户端,一旦被读取即可被复用 |
| 路径与域的作用范围 | 作用范围过宽会让不相关的请求都背上这个字段 |
实践要点
- 会话类状态尽量只放标识,把业务数据放在服务端,避免体积失控
- 敏感状态必须配齐安全属性,并只走加密连接
- 清理不再使用的状态项,历史遗留项会让每个请求都变大
浏览器会把作用域内的状态自动附加到所有相关请求上,因此大体积状态等于给每个请求都收一笔额外开销;而敏感会话状态如果缺少加密传输与禁止脚本读取属性,一次脚本注入就能把凭证完整偷走。
服务端不能假定请求里只有自己写入的状态:用户可能手工构造,也可能被其他组件写入。所有来自客户端的状态在服务端都必须重新校验,不能直接当作可信输入使用。