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

React调用Spring Security保护的Spring Boot接口返回401未认证问题

问题诊断

你的场景核心矛盾是同源策略限制导致跨域请求时Authorization头无法被后端正确接收,同时Spring Security默认的CORS配置未适配跨域认证需求,最终请求被标记为匿名请求返回401。

解决方案

1. 完善Spring Security的CORS配置

当前仅调用.cors()但未自定义规则,Spring默认CORS配置不允许携带自定义认证头或凭证。需添加自定义CORS配置源:

@Bean
CorsConfigurationSource corsConfigurationSource() {
    CorsConfiguration config = new CorsConfiguration();
    // 允许React所在的本地开发源
    config.setAllowedOrigins(Arrays.asList("http://localhost:3000"));
    // 允许所有请求方法
    config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS"));
    // 允许携带认证头、内容类型头
    config.setAllowedHeaders(Arrays.asList("Authorization", "Content-Type"));
    // 允许跨域请求携带凭证(认证头、Cookie等)
    config.setAllowCredentials(true);
    
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    // 对所有接口路径应用CORS规则
    source.registerCorsConfiguration("/**", config);
    return source;
}

在SecurityFilterChain中关联自定义配置,替换原有的.cors():

http.authorizeHttpRequests(auth -> auth
        .requestMatchers(HttpMethod.POST , "/api/users").permitAll()
        .requestMatchers( "/api/authority").hasAuthority(Constants.ADMIN)
        .anyRequest().authenticated()
    )
    // 绑定自定义CORS配置
    .cors(cors -> cors.configurationSource(corsConfigurationSource()))
    .formLogin().permitAll()
    .and().logout().permitAll()
    .and().userDetailsService(userDetailsService)
    .csrf().disable()
    .httpBasic();

2. 修正React的Fetch请求写法

跨域请求携带Authorization头时,必须开启credentials选项,否则浏览器会自动丢弃认证头:

var myHeaders = new Headers();
myHeaders.append("Authorization", "Basic " + btoa("root:root"));

const res = await fetch("http://localhost:7979/api/users", {
  method: 'GET',
  headers: myHeaders,
  credentials: 'include' // 关键:允许跨域携带认证凭证
})
console.log(res);
const data = await res.json();
console.log(data);

3. 确认WSL与Windows的网络连通性(针对WSL运行React场景)

如果React在WSL中运行,需确保WSL能访问Windows侧的Spring服务:

  • 检查WSL的/etc/hosts是否包含127.0.0.1 localhost,或直接使用Windows本地IP(通过ipconfig查看以太网适配器WSL的IPv4地址)访问接口
  • 在Spring的CORS配置中添加该IP作为允许的源,比如"http://192.168.x.x:3000"

4. 验证认证头是否被正确传递

可在Spring后端添加拦截器,打印请求头确认Authorization是否被接收:

@Component
public class RequestLoggingFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        System.out.println("Authorization Header: " + request.getHeader("Authorization"));
        filterChain.doFilter(request, response);
    }
}

注册该过滤器:

@Bean
FilterRegistrationBean<RequestLoggingFilter> loggingFilter() {
    FilterRegistrationBean<RequestLoggingFilter> registrationBean = new FilterRegistrationBean<>();
    registrationBean.setFilter(new RequestLoggingFilter());
    registrationBean.addUrlPatterns("/api/*");
    return registrationBean;
}

如果打印结果为null,说明浏览器未发送Authorization头,需重新检查CORS配置和Fetch的credentials选项。

关键注意事项
  • 跨域请求会先发送OPTIONS预检请求,上述CORS配置已允许所有方法(包含OPTIONS),确保预检请求能正常通过
  • 确认后端存储的密码是BCrypt加密后的对应值,比如root加密后的字符串要与前端传入的明文匹配

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 09:46:05