cookie的SameSite属性

SameSite 是 Cookie 的一种属性,主要用于防止跨站请求伪伪造(CSRF,Cross-Site Request Forgery)攻击。它通过控制第三方 Cookie 的发送时机,来保护用户的隐私和安全。

在深入 SameSite 之前,我们需要明确两个概念:

  • 第一方 Cookie (First-party Cookie): 你当前访问的网站(地址栏里的域名)写入的 Cookie。
  • 第三方 Cookie (Third-party Cookie): 页面中嵌入的其他网站(如广告、图片、iframe 插件)写入的 Cookie。

1. 核心概念:什么是"同站 (Same-Site)"?

SameSite 的"站(Site)"和我们平时说的"同源策略 (Same-Origin)"不同,它的定义更宽松。

满足以下条件的两个 URL 被认为是同站(Same-Site)的:

有效顶级域名 + 一级域名(eTLD+1) 相同

  • TLD 是指 .com、.org 等。
  • eTLD(有效顶级域名)是指像 .com.cn、.co.uk 这种复合域名。
  • 举个例子:
    • www.baidu.com 和 tieba.baidu.com 属于同站 (因为都是 baidu.com)。
    • baidu.com 和 google.com 属于跨站(Cross-Site)。
    • a.github.io 和 b.github.io 属于跨站 (因为 github.io 是一个 eTLD,它的下一级才是一级域名)。

2. SameSite 的三种策略值

SameSite 属性可以设置三个值:Strict、Lax 和 None。

① SameSite=Strict (严格模式)

这是最安全的模式。

  • 规则: 任何跨站的请求(无论通过什么方式触发)都绝不发送该 Cookie。只有当你在当前域名下操作,或者地址栏域名完全一致时才会携带。
  • 场景: 比如你在百度(baidu.com)页面里点击了一个指向淘宝(taobao.com)的链接。即使你之前在淘宝登录过,由于是跨站跳转,浏览器在请求淘宝时不会 带上淘宝的 Strict Cookie。
  • 优缺点: 防御 CSRF 效果最好,但极度影响用户体验(比如从邮件里点开一个知乎链接,进去了却发现需要重新登录)。

② SameSite=Lax (宽松模式)

这是目前主流浏览器的默认模式(平衡了安全与体验)。

  • 规则: 拒绝大部分跨站 Cookie 的发送,但允许"导航到目标网址的常规安全跳转"携带 Cookie。
  • 具体而言,只有满足以下两个条件时,跨站请求才会带上 Lax Cookie:
    1. HTTP 方法必须是安全的(通常是 GET) 。POST、PUT、DELETE 等绝对不带。
    2. 必须是顶级导航(Top-level navigation),即该请求会导致浏览器地址栏的 URL 发生变化。
  • 允许带 Lax Cookie 的场景:
    • <a href="..."> 链接跳转。
    • <link rel="prerender" href="..."> 预加载。
    • window.location.replace("...") 或表格的 GET 提交。
  • 禁止带 Lax Cookie 的场景:
    • ajax / fetch 请求。
    • <img src="...">、<iframe src="...">、<script src="..."> 等隐式加载的资源。
    • POST 表单提交。

③ SameSite=None (无限制)

关闭 SameSite 限制。

  • 规则: 无论同站还是跨站,任何请求都会带上 Cookie(回到了当年的传统行为)。
  • 硬性前提条件: 现代浏览器(Chromium 80 及以上)规定,如果设置了 SameSite=None,就必须同时设置 Secure 属性 。这意味着该 Cookie 只能通过 HTTPS 协议传输,否则浏览器会直接拒绝写入该 Cookie。
  • 场景: 专门用于第三方广告追踪、跨域共享状态、内嵌的第三方 iframe 支付插件等。

3. 三种策略的对比表格

请求类型 示例代码 Strict Lax (默认) None (+Secure)
链接跳转 (GET) <a href="https://site.com"> ❌ 不发送 ✅ 发送 ✅ 发送
预加载 (GET) <link rel="prerender" href="..."> ❌ 不发送 ✅ 发送 ✅ 发送
表单提交 (GET) <form method="GET" action="..."> ❌ 不发送 ✅ 发送 ✅ 发送
表单提交 (POST) <form method="POST" action="..."> ❌ 不发送 ❌ 不发送 ✅ 发送
图片/脚本加载 <img src="...">, <script src="..."> ❌ 不发送 ❌ 不发送 ✅ 发送
框架嵌套 <iframe src="..."> ❌ 不发送 ❌ 不发送 ✅ 发送
异步请求 fetch("..."), axios.get("...") ❌ 不发送 ❌ 不发送 ✅ 发送

4. 如何在服务器端设置?

在 HTTP 响应头(Response Headers)中,通过 Set-Cookie 来指定:

HTTP

复制代码
# 严格模式
Set-Cookie: sid=abc123; SameSite=Strict; Secure

# 默认的宽松模式
Set-Cookie: sid=abc123; SameSite=Lax

# 允许第三方使用(必须带 Secure)
Set-Cookie: sid=abc123; SameSite=None; Secure

5. 总结与开发建议

  1. 敏感操作防范: 涉及修改用户数据、资金安全、核心业务的 Cookie,尽量设为 Strict。
  2. 常规会话(Session ID): 保持默认的 Lax 即可,既能防御绝大多数 POST/AJAX 形式的 CSRF 攻击,又不会破坏正常的链接跳转体验。
  3. 跨域共享: 如果你的系统是分布式架构,且使用了不同的一级域名(比如微服务 A 域名是 aaa.com,B 域名是 bbb.com),且需要跨域携带 Cookie,必须使用 SameSite=None; Secure,并确保全站走 HTTPS。
相关推荐
NetX行者1 小时前
Rust 初体验:一个全栈工程师的编译器“毒打“笔记
开发语言·笔记·rust
热爱生活的五柒2 小时前
zotero能导入已经下载好的pdf文件嘛,并且点击条目时,能直接看到下载的pdf文件嘛,我还希望能在里面做笔记
笔记·pdf
海绵宝宝转agent3 小时前
2026-10-19学习笔记
笔记·学习
金色光环3 小时前
【概率论详细笔记】泊松分布是怎么来的?应该怎么用?
笔记·概率论
又見山3 小时前
双向链接的本质:链接不是功能,是思考留下的痕迹
笔记·obsidian
云水初3 小时前
【agent篇】RAG Agent避坑指南(附高级RAG Agent汇总)
开发语言·笔记·python·学习·langchain·agent·rag
JasmineX-14 小时前
数据结构(笔记)——顺序栈
c语言·数据结构·笔记
坤坤子吖4 小时前
Linux 线程同步与互斥——互斥锁
linux·服务器·c++·笔记·学习
撩得Android一次心动4 小时前
Jetpack Compose 知识点整理3【个人用】
android·笔记·学习·kotlin·android compose
威嵌神州5 小时前
国产化加固计算机项目选型笔记|板卡、整机、平板与定制模块评估要点
笔记·fpga开发·电脑