Double Submit Cookie如何防止CSRF攻击?我的实现总出现跨域问题怎么办?

シ莉莉 阅读 75

我按照教程实现了双重提交Cookie,后端设置了CSRF-TOKEN到Cookie和响应头,前端在请求头带上这个Token。但测试时发现,跨域请求时浏览器报“Blocked cookie with same-site=inherited path=/”错误,这是为什么呢?

我的代码是这样的:

<script>
document.cookie = CSRF-TOKEN=${response.csrfToken}; Path=/; HttpOnly; Secure; // 这里是不是哪里写错了?

fetch('/api/data', {
  method: 'POST',
  headers: {
    'X-CSRF-Token': response.csrfToken // 这样传递对吗?
  }
});
</script>

后端是Node.js,设置了CORS允许特定域名,但跨域请求时Cookie没自动带上,手动加到header反而被拦截了。是不是SameSite属性没配对?或者双重提交和CORS有冲突?

我来解答 赞 3 收藏
二维码
手机扫码查看
2 条解答
UI鑫玉
UI鑫玉 Lv1
你这个报错是因为Cookie的SameSite属性设置有问题,而且写法本身就有几个错误点。

首先,document.cookie 这行代码不能这么写。HttpOnly的Cookie是禁止前端JS读写的,你现在既要前端拿到Token,又要设HttpOnly,这本身就矛盾了。双重提交的核心是:Token必须能被前端获取并放到请求头里,所以这个Cookie绝对不能加HttpOnly。

你应该这样设Cookie:
res.setHeader('Set-Cookie', 'CSRF-TOKEN=' + token + '; Path=/; Secure; SameSite=None;')

注意三点:1)去掉HttpOnly;2)跨域要带Cookie必须配SameSite=None;3)必须同时有Secure,否则浏览器会拒绝。

然后前端才能通过document.cookie读到它。不过更推荐的方式是在页面初始化时直接把Token内联到HTML里,比如服务端渲染个window.CSRF_TOKEN = "xxx",避免解析cookie字符串。

另外CORS这块,fetch默认不会带凭证,你要加上credentials: 'include'
fetch('/api/data', {
method: 'POST',
credentials: 'include',
headers: {
'X-CSRF-Token': token
}
});


后端CORS中间件也要确认开了credentials: true,允许Origin精确匹配,不能用*。

最后提醒一点,双重提交的前提是你的站点没有XSS漏洞,否则Token就直接被偷了。如果存在富文本之类的功能,建议配合Samesite=Lax或者用同步Token模式更安全。
点赞 4
2026-02-09 09:29
Code°朱莉
你这个情况是典型的跨域场景下Cookie策略配置不当导致的。先检查一下设置Cookie的方式。你当前的代码里用的是document.cookie来写入Token,这种方式在跨域情况下基本没用,而且属性写法还有问题——属性值需要用引号包裹,并且SameSite没设置。你现在的写法会导致Cookie根本无法正确保存。

另外,你后端设置CORS的时候,必须开启credentials支持,否则浏览器不会自动带上Cookie。前端fetch请求时也要加上credentials: 'include',否则跨域请求也不会带Cookie。

再看你的双重提交实现方式:前端在请求头里加X-CSRF-Token是对的,但前提是后端确实验证了这个Header的值。不过当你用fetch的时候,如果跨域,而且Cookie又没正确带上,就会出现Token不一致的问题。

下面是几个关键修复点:

1. **不要用 document.cookie 手动写入Token**,应该由后端通过真实的 Set-Cookie 头来设置,比如:

Set-Cookie: CSRF-TOKEN=abc123; Path=/; Secure; HttpOnly; SameSite=Strict


2. **前端 fetch 请求加上 credentials 选项**:


fetch('https://your-api.com/api/data', {
method: 'POST',
credentials: 'include',
headers: {
'X-CSRF-Token': csrfToken
}
});


3. **后端CORS配置要允许凭据**(Node.js Express 示例):


app.use(cors({
origin: 'https://your-frontend.com',
credentials: true
}));


4. **确保后端接口的 SameSite 策略允许跨域携带Cookie**:
- 如果你是前后端不同域名,那SameSite=Strict是不行的,只能设为 Lax 或者显式用 SameSite=None 并配合 Secure 属性。

总结一下:你现在的问题核心是Cookie没正确设置 + 跨域凭据没启用。先按上面几个点调整,应该就能解决跨域下Token带不过去的问题。Double Submit本身和CORS不冲突,只是需要正确配置Cookie策略和CORS凭据支持。
点赞 9
2026-02-03 20:17