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

React+Spring Boot中Axios POST请求CSRF配置及登录CORS错误排查

问题分析与解决方案

看起来你遇到的核心问题是CORS配置的允许请求头与实际发送的请求头不匹配,再加上Axios的CSRF令牌传递方式有误,导致预请求(OPTIONS)失败。下面一步步帮你修正:

1. 修正CORS配置的允许请求头

你的错误提示明确说x-xsrf-token不被Access-Control-Allow-Headers允许,但看你的CORS配置里只加了xsrf-token,而实际请求里发送的是X-XSRF-TOKEN(注意大小写)。另外,当开启AllowCredentials=true时,AllowedOrigins不能用*,必须指定具体的前端域名,否则浏览器会拒绝跨域请求。修改后的CORS配置如下:

@Bean
public CorsConfigurationSource corsConfigurationSource() {
    CorsConfiguration configuration = new CorsConfiguration();
    // 替换为你的React实际域名,不能用*
    configuration.setAllowedOrigins(Arrays.asList("http://localhost:3000"));
    configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"));
    configuration.setAllowCredentials(true);
    // 加入实际发送的X-XSRF-TOKEN请求头
    configuration.setAllowedHeaders(Arrays.asList("authorization", "Cache-Control", "content-type", "X-XSRF-TOKEN"));
    configuration.setExposedHeaders(Arrays.asList("X-XSRF-TOKEN"));
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", configuration);
    return source;
}

2. 修正Axios的请求配置

你把Axios的xsrfCookieName和xsrfHeaderName放在了headers里,这是错误的——这两个是Axios的全局/请求配置项,不是请求头的一部分。另外,Spring Security启用CSRF时,通过X-XSRF-TOKEN头传递令牌就足够了,不需要再在表单里加_csrf参数。修改后的Axios代码:

export const addProjectTask = (username,password,csrf,history) => async dispatch => {
    axios.post('http://localhost:8080/login', Qs.stringify({
        username: username,
        password: password
    }), {
        headers: {
            "X-XSRF-TOKEN": csrf,
            "Content-Type": "application/x-www-form-urlencoded"
        },
        credentials: 'include',
    })
    .then(function (response) {
        console.log(response);
        history.push("/");
    })
    .catch(function (error) {
        console.log(error);
    });
};

3. 确保Spring Security中CORS与CSRF的顺序正确

在Spring Security配置类中,必须让CORS过滤器优先于CSRF过滤器生效,同时建议配置CookieCsrfTokenRepository,方便后续扩展(比如让Axios自动从Cookie读取令牌):

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private CorsConfigurationSource corsConfigurationSource;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            // 先启用CORS,确保CORS过滤器在CSRF之前执行
            .cors().configurationSource(corsConfigurationSource)
            .and()
            .csrf()
                // 设置Cookie的HttpOnly为false,允许前端读取XSRF-TOKEN Cookie
                .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
            .and()
            .authorizeRequests()
                .antMatchers("/login").permitAll()
                .anyRequest().authenticated()
            .and()
            .formLogin()
                .loginProcessingUrl("/login"); // 指定登录接口路径
    }
}

4. 验证请求与响应头

修改完成后,打开Chrome开发者工具的Network标签:

  • 查看OPTIONS预请求的响应头,确认Access-Control-Allow-Headers包含X-XSRF-TOKEN
  • 查看POST登录请求的请求头,确认X-XSRF-TOKEN已正确携带

内容的提问来源于stack exchange,提问作者vidy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 09:03:48