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

Spring Boot受保护资源通过React(Axios)访问遇CORS错误,Postman正常

问题排查与解决:Axios带Authorization头访问Spring Boot资源出现CORS错误

核心原因

Postman不会触发浏览器的CORS预检机制,但浏览器发送带Authorization这类自定义头的请求时,会先发送OPTIONS预检请求。当前配置存在两个关键问题:

  • Spring Security过滤器优先级高于WebMvc的CORS配置,导致OPTIONS预检请求被Security认证逻辑拦截,无法返回正确的CORS响应头
  • 客户端Axios配置中Accept头设置错误(写为"/",正确应为"*/*"),可能触发预检请求的头校验失败

解决办法

方案一:在Spring Security中直接集成CORS配置(推荐)

放弃WebMvcConfigurer的CORS配置,改用Spring Security原生CORS配置,确保CORS过滤器在认证过滤器之前执行:

修改SecurityConfig类:

package com.telesco.demo.security;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import com.telesco.demo.services.MyUserDetailsService;
import org.springframework.http.HttpMethod;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Autowired
    private MyUserDetailsService userDetailsService;

    @Autowired
    private JwtFilter jwtFilter;

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        return http.csrf(customizer -> customizer.disable())
                // 启用Spring Security原生CORS支持
                .cors(Customizer.withDefaults())
                .authorizeHttpRequests(request -> request
                        .requestMatchers("api/register", "api/franchise/login", "publicquery", "api/isUserIdAvailable")
                        .permitAll()
                        // 允许所有OPTIONS预检请求直接通过
                        .requestMatchers(HttpMethod.OPTIONS, "/**").permitAll()
                        .anyRequest().authenticated())
                .httpBasic(Customizer.withDefaults())
                .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                .addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class).build();
    }

    @Bean
    public AuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
        provider.setPasswordEncoder(new BCryptPasswordEncoder(12));
        provider.setUserDetailsService(userDetailsService);
        return provider;
    }

    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {
        return config.getAuthenticationManager();
    }

    // 配置全局CORS规则
    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(java.util.List.of("http://localhost:5173"));
        configuration.setAllowedMethods(java.util.List.of("GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH", "HEAD", "TRACE"));
        configuration.setAllowedHeaders(java.util.List.of("*"));
        // 允许携带Cookie等凭证(根据业务需求调整)
        configuration.setAllowCredentials(true);
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }
}

方案二:修复客户端Axios配置错误

修正Accept头的错误值,将"/"改为符合规范的"*/*":

api.interceptors.request.use(
  (config) => {
    const token = localStorage.getItem("token");
    if (token) {
      config.headers.Authorization = `Bearer ${token}`;
      config.headers["Content-Type"] = "application/json";
      // 修正Accept头为标准通配符格式
      config.headers["Accept"] = "*/*";
      config.headers["Accept-Encoding"] = "gzip, deflate, br";
      config.headers["Connection"] = "keep-alive";
    }
    return config;
  },
  (error) => Promise.reject(error)
);

验证步骤

  1. 重启Spring Boot服务
  2. 清除浏览器缓存后重新登录获取token
  3. 访问受保护资源/api/items,此时浏览器OPTIONS预检请求会被正确处理,CORS错误消失

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 04:19:56