You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 06:15:54