NextJS前端+Spring Security后端CSRF配置异常:POST请求失败求助
解决NextJS + Spring Boot开启CSRF后POST请求失败的问题
核心问题分析
你的问题集中在跨域场景下CSRF Token的存储、携带逻辑,以及Spring Security配置的细节疏漏上,以下是针对性的修复步骤:
1. 修复Spring Security的CSRF Cookie配置
你的现有配置存在两个关键问题:
- 本地开发环境使用HTTP协议,设置
cookie.secure(true)会导致浏览器拒绝在HTTP请求中携带该Cookie(Secure属性仅允许HTTPS传输) - 配置代码不完整,未将自定义的
CookieCsrfTokenRepository绑定到Spring Security的CSRF规则中
修改后的完整配置:
http .csrf(csrf -> { CookieCsrfTokenRepository cookieCsrfTokenRepository = CookieCsrfTokenRepository.withHttpOnlyFalse(); cookieCsrfTokenRepository.setCookieCustomizer(cookie -> { cookie.sameSite("None"); cookie.maxAge(3600L); cookie.httpOnly(false); // 本地开发改为false,生产环境部署HTTPS后再改回true cookie.secure(false); cookie.domain("localhost"); }); // 必须添加此行,将自定义Token仓库绑定到CSRF配置 csrf.csrfTokenRepository(cookieCsrfTokenRepository); });
2. 修复前端CSRF Token的获取与携带逻辑
2.1 确保GET请求正确存储Cookie
跨域请求下,必须显式设置credentials: 'include',浏览器才会保存后端返回的Cookie,否则Cookie不会被写入本地:
const response = await fetch(apiEndpoint(RequestURL.csrfToken), { credentials: 'include', // 取消注释并启用这行 });
2.2 POST请求需主动携带XSRF Token到请求头
Spring Security的CookieCsrfTokenRepository默认从**请求头X-XSRF-TOKEN**中读取Token值,而非自动读取Cookie。你需要从Cookie中提取XSRF-TOKEN的值,手动添加到POST请求的头里:
// 新增工具函数:从Cookie中提取XSRF-TOKEN const getXsrfToken = () => { const cookies = document.cookie.split('; '); for (const cookie of cookies) { const [name, value] = cookie.split('='); if (name === 'XSRF-TOKEN') { return decodeURIComponent(value); } } return ''; }; const fetchCsrf = async () => { console.log("get csrf begin"); const response = await fetch(apiEndpoint(RequestURL.csrfToken), { credentials: 'include', // 必须开启 }); console.log("get csrf complete: ", await response.json()); const xsrfToken = getXsrfToken(); console.log("--- XSRF-TOKEN = ", xsrfToken); const response1 = await fetch("http://localhost:8081/api/auth/test", { method: "POST", credentials: "include", headers: { 'X-XSRF-TOKEN': xsrfToken, // 携带Token到请求头 'Content-Type': 'application/json' // 若发送JSON数据需添加此头 } }); console.log("response1 = ", await response1.json()); }
3. 额外验证点
- 确认Spring Boot的CORS配置允许携带自定义头
X-XSRF-TOKEN,需添加allowedHeaders("X-XSRF-TOKEN") - 打开浏览器控制台Network面板,检查POST请求的Request Headers是否包含
X-XSRF-TOKEN,Request Cookies是否包含XSRF-TOKEN - 本地测试时,确保浏览器未禁用第三方Cookie(跨域场景下需要允许第三方Cookie)
内容的提问来源于stack exchange,提问作者jacob
相关产品推荐
相关产品推荐

