Double Submit Cookie如何防止CSRF攻击?我的实现总出现跨域问题怎么办?
我按照教程实现了双重提交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有冲突?
首先,
document.cookie这行代码不能这么写。HttpOnly的Cookie是禁止前端JS读写的,你现在既要前端拿到Token,又要设HttpOnly,这本身就矛盾了。双重提交的核心是:Token必须能被前端获取并放到请求头里,所以这个Cookie绝对不能加HttpOnly。你应该这样设Cookie:
注意三点:1)去掉HttpOnly;2)跨域要带Cookie必须配
SameSite=None;3)必须同时有Secure,否则浏览器会拒绝。然后前端才能通过
document.cookie读到它。不过更推荐的方式是在页面初始化时直接把Token内联到HTML里,比如服务端渲染个window.CSRF_TOKEN = "xxx",避免解析cookie字符串。另外CORS这块,fetch默认不会带凭证,你要加上
credentials: 'include':后端CORS中间件也要确认开了
credentials: true,允许Origin精确匹配,不能用*。最后提醒一点,双重提交的前提是你的站点没有XSS漏洞,否则Token就直接被偷了。如果存在富文本之类的功能,建议配合Samesite=Lax或者用同步Token模式更安全。
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头来设置,比如:2. **前端 fetch 请求加上
credentials选项**:3. **后端CORS配置要允许凭据**(Node.js Express 示例):
4. **确保后端接口的
SameSite策略允许跨域携带Cookie**:- 如果你是前后端不同域名,那
SameSite=Strict是不行的,只能设为Lax或者显式用SameSite=None并配合Secure属性。总结一下:你现在的问题核心是Cookie没正确设置 + 跨域凭据没启用。先按上面几个点调整,应该就能解决跨域下Token带不过去的问题。Double Submit本身和CORS不冲突,只是需要正确配置Cookie策略和CORS凭据支持。