SameSite
SameSite Cookie 属性的站点判定方式、自动携带边界与三种策略说明
#tech / dev / frontend
#type / concept
#status / evergreen
#platform / browser
[!info] related notes
- 所属 MOC: frontend-basics-moc
- 相关概念: same-origin, csrf, cookie-vs-localstorage, cookie-session-token
SameSite
Overview
同站 (Same-Site):基于有效顶级域名(eTLD)+ 1 个二级域名来判断。只要 eTLD+1 相同,就被认为是同站。例如,https://a.example.com 和 https://b.example.com 属于同站(它们的 eTLD+1 都是 example.com),尽管它们跨源。
Cookie 自动携带机制
浏览器发送请求时,会先按目标域匹配 Cookie,再结合 SameSite 决定跨站场景是否允许附带。
- 同站请求:通常正常携带 Cookie
- 跨站顶级导航:
Lax下部分允许 - 跨站子资源或 AJAX:通常会被限制
浏览器中的属性头
SameSite 属性的三个值
SameSite 属性有三个可选值,决定了浏览器在跨站请求时对 Cookie 的处理策略:
1. SameSite=Strict(最严格)
- 含义:完全禁止第三方 Cookie。只有当请求发起方的站点与目标站点的 URL 完全属于“同站”时,浏览器才会发送 Cookie。
- 场景:极大地提高了安全性,但牺牲了用户体验。例如,如果你在微信里点击了一个知乎的链接,即使你之前已经登录过知乎,由于是从微信(跨站)跳转过去的,浏览器也不会携带知乎的 Cookie,你会发现自己处于未登录状态,需要重新登录。
- 适用:涉及高度敏感操作的系统(如银行内部转账接口)。
2. SameSite=Lax(现代浏览器默认值)
- 含义:一种相对宽松的规则,旨在平衡安全性和用户体验。它允许部分跨站请求携带 Cookie。
- 规则:
- 阻止:跨站的
POST请求、AJAX请求(fetch/XHR)、以及作为第三方资源加载的请求(如<img>、<iframe>、<script>)不携带 Cookie。 - 允许:对于引起“顶级导航”的“安全 HTTP 方法”(主要是
GET请求),允许携带 Cookie。例如,点击<a>标签链接、预加载<link rel="prerender">、通过window.location跳转。
- 阻止:跨站的
- 场景:如果你在外部网站点击了一个淘宝的链接跳转过去,你会发现你依然是登录状态(因为是 GET 顶级导航);但如果外部网站试图静默向淘宝发送一个 POST 请求(比如购买商品),Cookie 就不会被携带。
3. SameSite=None(无限制)
- 含义:关闭
SameSite限制,无论是否跨站,浏览器都会发送 Cookie。 - 前提条件:从 2020 年开始,主流浏览器要求,如果设置了
SameSite=None,则必须同时设置Secure属性(即Set-Cookie: key=value; SameSite=None; Secure)。这意味着 Cookie 只能在 HTTPS 环境下跨站发送。 - 适用:单点登录(SSO)、第三方支付嵌入、跨站跟踪广告等确实需要第三方 Cookie 的场景。