本文目录导读:

SameSite 是 HTTP Cookie 中的一个安全属性,旨在控制第三方上下文中 Cookie 的发送行为,从而防止跨站请求伪造(CSRF)攻击。
它决定了:当用户从一个网站(如 A.com)点击链接或提交表单跳转到另一个网站(如 B.com)时,浏览器是否应该将 B.com 的 Cookie 一起发送过去。
三个核心值
SameSite 属性有 3 个可选值,行为如下:
| 值 | 行为 | 典型场景与安全性 |
|---|---|---|
| Strict | 最严格,浏览器只在第一方上下文中发送 Cookie,即只有当访问的网站(地址栏里的域名)与设置 Cookie 的网站完全一致时,才发送。 | 优点:防御 CSRF 能力最强。 缺点:用户体验差,例如用户从 Google 搜索跳转到你的网站,如果未登录,无法识别身份(因为登录 Cookie 没发过去)。 |
| Lax | 默认值(现代浏览器的默认行为),允许在顶级导航(Top-level navigation)中使用 GET 方法发送 Cookie。 | 优点:平衡了安全与体验,用户从外部链接(如邮件、搜索引擎)跳转时可以保持登录状态。 缺点:无法防御通过 POST 表单提交或 JavaScript 发起的 CSRF。 |
| None | 无限制,Cookie 可以在任何上下文中发送(第一方和第三方),但必须同时设置 Secure 属性(即只能在 HTTPS 下传输)。 |
用途:跨域调用(如第三方支付、单点登录、嵌入的 iframe)。 风险:容易受到 CSRF 攻击,必须确保目标接口有额外的防 CSRF 机制(如 Token 验证)。 |
设置方式
在服务端响应头中设置:
Set-Cookie: sessionId=abc123; SameSite=Lax Set-Cookie: apiToken=xyz789; SameSite=None; Secure
在 JavaScript 中(通过 document.cookie 设置时会忽略 SameSite 属性,建议服务端设置)。
常见问题与误区
-
SameSite 能完全防 CSRF 吗?
- 不能完全。
Strict能防大部分,但会牺牲体验。Lax无法防御通过 POST 表单提交的 CSRF。None几乎没有防御作用(需要配合 CSRF Token 使用)。
- 不能完全。
-
SameSite 与跨域请求(CORS)的关系
- 不是一回事。CORS 控制的是跨域请求是否能发送/读取响应数据。SameSite 控制的是浏览器是否携带该域名下的 Cookie。
- 跨域请求即使通过 CORS 允许了,Cookie 设置
SameSite=Strict或Lax,也仍然不会携带。
-
SameSite 与跨站(cross-site)还是跨域(cross-origin)?
- SameSite 关心的是“跨站”(不同站点),而不是“跨域”(不同子域名或端口)。
a.example.com和b.example.com→ 同站(顶级域名相同)example.com和another.com→ 跨站
- SameSite 关心的是“跨站”(不同站点),而不是“跨域”(不同子域名或端口)。
-
第三方 Cookie 限制
- 许多浏览器(如 Chrome、Safari)默认将未设置
SameSite的 Cookie 视为SameSite=Lax,对于需要跨站使用的第三方 Cookie(如嵌入的支付页面),必须显式设置为SameSite=None; Secure。
- 许多浏览器(如 Chrome、Safari)默认将未设置
建议实践
- 一般业务场景(网站自己的登录状态、购物车等):使用
SameSite=Lax(默认值,不显式设置也行)。 - 高安全要求场景(如银行转账、用户信息修改的会话):使用
SameSite=Strict,同时告知用户不要从外部链接直接访问敏感操作页面。 - 第三方服务(如支付回调、SSO、嵌入的 iframe):使用
SameSite=None; Secure,并配合HttpOnly和 CSRF Token。 - 重要补充:始终使用
Secure属性,确保 Cookie 只在 HTTPS 下传输。
SameSite 属性是浏览器针对 Cookie 的“跨站发送许可证”,Strict 只允许本站使用,Lax 允许 GET 方式的跳转使用,None 允许任何场景使用(但必须 HTTPS)。