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

Spring OAuth2认证:Postman正常但Vue客户端请求oauth/token返回401

解决Spring OAuth跨域请求返回401的问题

看起来你遇到的是跨域预飞行请求(OPTIONS)被Spring Security拦截返回401的问题——浏览器在发送带Basic Auth的POST这类非简单请求前,会先发送OPTIONS请求做预检,而你的OAuth端点默认受Spring Security保护,OPTIONS请求没携带认证信息就被拒绝了。下面是具体的修复步骤:

1. 修正CORS配置的路径映射

你当前的CORS配置只匹配/*,只能覆盖一级路径(比如/test),但/oauth/token是二级路径,得把映射改成/**来覆盖所有路径,同时加上支持凭证的配置:

@Bean
public WebMvcConfigurer corsConfigurer() {
    return new WebMvcConfigurerAdapter() {
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**") // 修改为/**匹配所有路径
                    .allowedOrigins("http://localhost:8080")
                    .allowedHeaders("*")
                    .allowedMethods("*")
                    .allowCredentials(true); // 开启凭证支持,适配Basic Auth场景
        }
    };
}

2. 配置Spring Security放行OPTIONS请求

Spring Security默认会拦截所有请求,包括OPTIONS预飞行请求,你需要在Security配置里明确放行OPTIONS,同时确保CORS过滤器优先执行:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .cors() // 启用CORS支持
            .and()
            .authorizeRequests()
            .antMatchers(HttpMethod.OPTIONS, "/**").permitAll() // 放行所有OPTIONS预检请求
            .anyRequest().authenticated();
        // 保留你原有的其他Security配置
    }

    // 如果使用OAuth2,还要在授权服务器配置里确保OPTIONS请求能通过
    @Configuration
    @EnableAuthorizationServer
    public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
        @Override
        public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
            security
                .allowFormAuthenticationForClients()
                .checkTokenAccess("isAuthenticated()")
                .tokenKeyAccess("permitAll()");
        }
    }
}

3. 修正Vue客户端的请求配置

你的客户端请求里有个错误:不要发送Access-Control-Allow-Origin请求头——这个头是服务器返回给浏览器的,不是客户端需要发送的。另外axios的auth字段会自动处理Basic Auth的请求头,不需要额外配置:

var params = new URLSearchParams();
params.append('grant_type', 'password');
params.append('username', 'username1');
params.append('password', 'password1');
axios({
    method:'POST',
    baseURL: `http://localhost:8088/`,
    url: 'oauth/token',
    auth: { username:'my-trusted-client', password:'secret' },
    headers: {
        // 移除Access-Control-Allow-Origin头
        "Content-type": "application/x-www-form-urlencoded; charset=utf-8"
    },
    data: params
}).then ((response) => { console.log (response) })
  .catch ((error) => { console.log (error) })

问题根源说明

当浏览器发送跨域的非简单请求(比如带Basic Auth、自定义头的POST)时,会先发送OPTIONS预飞行请求,询问服务器是否允许该跨域请求。如果这个OPTIONS请求被Spring Security拦截返回401,浏览器就会判定跨域不被允许,直接终止后续的POST请求,也就是你看到的Response for preflight has invalid HTTP status code 401错误。

按上面的步骤调整后,应该就能正常获取token了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:41:32