← 中文资源

简体中文版本

SameSite=Lax — 跨站 POST 不带 Cookie

诊断导航正常但跨站 POST 与 iframe 中消失的会话,理解 Lax 默认语义,并修流程结构或 Cookie 策略。

阅读英文原文

症状

  分裂形态是最强提示:会话在一切普通导航中正常,但第三方一 POST 回来(支付回调、老式 SSO),请求就以匿名身份到达。网络面板一目了然——同站 GET 带 cookie、跨站 POST 什么都没有。Set-Cookie 行在没有任何服务端 bug 的情况下解释了原因:SameSite=Lax 允许顶层 GET 导航携带,跨站 POST 与 iframe 一律扣留。浏览器默认 Lax 之后,曾经正常的 POST-back 流程变成了静默登出。旧浏览器或关闭 SameSite 的测试配置档正常,是环境对照证据。

诊断思路

  先在网络面板对比同一 cookie 在不同请求类型上的出现与缺席;再读 Set-Cookie 的属性——Lax 或缺省(现代浏览器缺省即 Lax)就足以解释 POST 缺失;最后给流程形态分类:第三方经 POST-back 还是重定向回来,决定是重塑流程还是显式放宽 cookie。跨站子资源 XHR 不带凭证同样是 Lax 的设计行为,不是 bug。

根因

  SameSite=Lax 只允许同站请求与安全方法(GET)的顶层导航携带 cookie。跨站 POST——支付回调、来自其他源 的表单自动提交——两者皆非,浏览器扣留会话 cookie,接收端把用户当匿名处理。

修复与验证

  优先重塑流程:改为顶层 GET 重定向加服务端一次性令牌——provider 重定向到 /payments/callback?token=0f8a3e9c,服务端校验令牌、查找待办操作、应用后继续重定向。POST-back 被外部提供方写死时,为那一个 cookie 显式设 SameSite=None; Secure(None 必须带 Secure,否则浏览器拒绝),并成对补上 CSRF 令牌防御——每个 None 都重新打开 Lax 关闭的跨站携带,放宽的 cookie 数量压到集成真正所需的最小值。验证时回调流程带着完整会话完成;跨站 POST 只有被刻意放宽的那个 cookie 生效;伪造请求仍被 CSRF 防护拦截。

代码示例

Set-Cookie: session=abc123; Path=/; HttpOnly; SameSite=Lax
provider -> redirect GET /payments/callback?token=one-time-id
server: validate token, look up pending operation, apply, redirect onward
Set-Cookie: session=abc123; Path=/; HttpOnly;
            Secure; SameSite=None