主题
Cookie
设置、发送与响应读取
服务器通过响应头 Set-Cookie 请求浏览器保存键值及其属性。浏览器在后续符合条件的请求中通过 Cookie 发送键值,属性留在浏览器中供匹配使用。一个响应可有多个独立的 Set-Cookie 字段。
- 接受设置取决于属性是否合法、Fetch 的凭证模式和浏览器的存储策略。设置成功后,后续请求仍要重新匹配发送条件。
- 随请求发送取决于域、路径、过期时间、安全连接、同站关系、凭证模式和浏览器隐私策略。跨站 Cookie 即使配置了
SameSite=None; Secure,也可能被阻止或分区。 - 向脚本开放响应由同源策略和 CORS 决定。简单跨源请求可能已携带 Cookie 到达服务器,脚本却读不到响应。预检失败则会阻止正式请求。即使响应可读,浏览器也不会向脚本暴露
Set-Cookie。
Domain
省略时为 host-only,仅匹配设置它的主机。指定当前域或合法父域时,也可匹配子域。其他域或公共后缀通常会被拒绝。Cookie 的域匹配不按端口隔离。
Path
匹配相同路径或以斜杠为边界的下级路径。省略时取请求路径的目录部分,空目录使用 /。例如在 /auth/login 设置时,默认路径为 /auth,匹配 /auth 和 /auth/profile,不匹配 /authentication。
token=AAA; Path=/ 和 token=BBB; Path=/admin 可以同时随 /admin/users 发送。请求头不包含路径,服务端不应依赖同名值的排列顺序。Path 不构成安全隔离。
Max-Age 与 Expires
Max-Age 指定剩余秒数,Expires 指定绝对过期时间。两者都有效时优先使用 Max-Age。都省略时为会话 Cookie,浏览器恢复会话时可能保留它。
设置 Max-Age=0 可清除 Cookie。要清除前例中 /admin 下的值,需要匹配原名称、域和路径,使用分区存储时还需匹配分区。
Secure
通常要求在 HTTPS 上设置和发送。
HttpOnly
禁止页面脚本通过 document.cookie 读取或直接修改该 Cookie。浏览器仍可在满足条件时自动发送,因此 HttpOnly 无法单独防止 CSRF。
SameSite
| 值 | 发送条件 |
|---|---|
Strict | 仅同站请求。 |
Lax | 同站请求,以及使用 GET 等安全方法的跨站顶级导航。 |
None | 允许跨站发送,需要同时设置 Secure,仍受浏览器隐私策略约束。 |
多数浏览器在省略时采用类似 Lax 的策略。部分浏览器允许刚设置的默认 Cookie 在短时间内随跨站顶级 POST 导航发送。
同源、同站与跨源凭证
同源比较协议、主机和端口。同站对常见 HTTP(S) 地址比较协议与可注册域。因此 https://app.example.com 和 https://api.example.com 同站但跨源。API 可设置仅属于自身的 host-only Cookie,浏览器请求 API 时仍可发送它。
Fetch 的 credentials | 浏览器 Cookie 行为 |
|---|---|
omit | 不发送 Cookie,也不处理响应中的 Set-Cookie。 |
same-origin(默认) | 同源请求允许发送和接收 Cookie。 |
include | 跨源请求也允许发送和接收 Cookie,仍受 Cookie 匹配规则和浏览器策略约束。 |
带凭证的跨源响应需返回明确的 Access-Control-Allow-Origin(不能用 *)和 Access-Control-Allow-Credentials: true,才可向页面脚本开放。跨源预检本身不带 Cookie。
