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

Spring Security 集成 React 跨域请求401认证问题排查求助

问题分析与解决方案

核心问题原因

  1. CORS配置未正确生效:你定义了CorsConfiguration但未将其注册为Spring Security的CORS配置源,导致自定义规则不生效;同时allowedOrigins设为*并开启allowCredentials=true,这违反浏览器跨域安全规则(带凭证的跨域请求不允许使用通配符域名)。
  2. 前端未携带认证凭证:Axios跨域请求默认不会携带Cookie,而Spring Security的HTTP Basic认证默认依赖会话Cookie识别用户,后续请求因无认证信息返回401。
  3. 登录接口与HTTP Basic机制冲突:自定义的/login接口手动处理认证,但未让前端正确保存或传递认证凭证,和Spring Security自带的HTTP Basic认证逻辑重复。

分步解决方案

1. 修复Spring Security的CORS配置

将自定义的CORS配置注册为CorsConfigurationSource,并指定具体的前端域名(禁止用*):

import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.cors.CorsConfigurationSource;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration corsConfig = new CorsConfiguration();
        // 替换为你的React实际域名,比如http://localhost:3000
        corsConfig.setAllowedOrigins(List.of("http://localhost:3000"));
        corsConfig.setAllowedHeaders(List.of("Authorization", "Cache-Control", "Content-Type"));
        corsConfig.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH"));
        corsConfig.setAllowCredentials(true);
        corsConfig.setExposedHeaders(List.of("Authorization"));

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", corsConfig);
        return source;
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        // 绑定自定义CORS配置源
        http.cors(cors -> cors.configurationSource(corsConfigurationSource()));
        http.csrf().disable();
        http.authorizeHttpRequests(auth -> auth
                .antMatchers("/user/login", "/swagger-resources/**", "/swagger-ui.html", "/webjars/**")
                .permitAll()
                .anyRequest().authenticated()
        )
        .httpBasic()
        .and()
        .logout(logout -> logout.logoutUrl("/logout"));

        return http.build();
    }
}

2. 前端Axios请求开启凭证携带

修改登录和银行列表请求,添加withCredentials: true,确保跨域时传递会话Cookie:

登录请求修改

const login = () => {
    axios.post("http://localhost:9091/v2/user/login", {
      user_id:"abc@abc.com",
      password:"123456"
    }, {
      withCredentials: true // 开启跨域凭证携带
    }).then(response => {
       setfirst(response.data);
       console.log(response.data);
     }).catch(error => {
       console.log("error", error);
       setfirst(error.response);
     });  
};

银行列表请求修改

const bank = () => {
    axios.get("http://localhost:9091/v2/bank", {
      withCredentials: true // 开启跨域凭证携带
    }).then(response => {
       console.log(response.data);
     }).catch(error => {
       console.log("error", error);
     });  
};

3. 优化认证方式(可选但推荐)

HTTP Basic认证依赖会话Cookie,在前后端分离场景下,更推荐使用JWT Token替代:

  1. 自定义登录接口验证成功后,生成JWT Token返回给前端。
  2. 前端将Token保存到localStorage或sessionStorage。
  3. 后续所有请求在请求头中携带Authorization: Bearer <Token>。
  4. Spring Security配置JWT过滤器,验证Token的合法性。

这种方式无需依赖Cookie,避免跨域凭证传递的问题,更适合前后端分离架构。


额外排查点

  • 检查浏览器控制台的跨域错误详情,确认是否是Access-Control-Allow-Origin不匹配或凭证未携带的问题。
  • 验证Spring Security是否正确拦截请求:可以在SecurityFilterChain中添加日志,确认CORS配置是否生效。
  • 生产环境禁止使用allowedOrigins: "*",必须指定具体的可信域名,避免安全风险。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 14:44:57