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

Angular发送Bearer Token时遇CORS问题:请求未携带Authorization头

我来帮你排查这个问题,这种情况我之前也碰到过,大概率是拦截器范围或者预检请求的处理逻辑没做好,咱们一步步来解决:

1. 先检查Angular拦截器的配置是否生效

首先要确认你的拦截器真的覆盖了所有请求(包括GET和OPTIONS),很多时候会不小心过滤掉某些请求类型,或者拦截器根本没注册成功。

拦截器核心代码要确保无遗漏

你的拦截器应该处理所有非登录类的请求,别漏掉GET:

@Injectable()
export class AuthInterceptor implements HttpInterceptor {
  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    // 从本地存储/认证服务获取token
    const authToken = localStorage.getItem('authToken');
    
    // 排除登录请求避免循环跳转,其余请求都添加Authorization头
    if (authToken && !request.url.includes('/login')) {
      const authReq = request.clone({
        setHeaders: {
          Authorization: `Bearer ${authToken}`
        },
        withCredentials: true // 跨域请求时需要带凭证的话必须加这个
      });
      return next.handle(authReq);
    }
    
    return next.handle(request);
  }
}

确认拦截器已在AppModule中注册

如果没注册,拦截器根本不会工作:

import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { AuthInterceptor } from './auth.interceptor';

@NgModule({
  // ...其他模块配置
  providers: [
    {
      provide: HTTP_INTERCEPTORS,
      useClass: AuthInterceptor,
      multi: true // 允许多个拦截器,这个参数不能忘
    }
  ]
})
export class AppModule { }

加日志验证拦截范围

在拦截器里加一行日志,看GET和OPTIONS请求是不是都经过了拦截器:

console.log(`拦截到请求:${request.method} ${request.url}`);

打开浏览器控制台,观察请求日志,如果OPTIONS请求没出现在日志里,那可能是你在请求里加了skipInterceptor的配置,得检查去掉。

2. 调整Spring Boot的CORS与Security配置

这是最容易踩坑的地方!浏览器的OPTIONS预检请求是自动发送的,后端必须允许它跳过认证,同时要明确允许Authorization请求头。

配置CORS允许必要的头和方法

@Configuration
public class CorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("http://localhost:4200") // 替换成你的Angular端口
                .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
                .allowedHeaders("Authorization", "Content-Type") // 明确允许Authorization头
                .allowCredentials(true)
                .maxAge(3600); // 预检请求缓存时间,减少重复请求
    }
}

让Spring Security放过OPTIONS请求

如果用了Spring Security,必须配置让OPTIONS请求不需要认证,否则预检请求会直接返回401:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors().and()
            .authorizeRequests()
            .antMatchers(HttpMethod.OPTIONS, "/**").permitAll() // 所有OPTIONS请求直接放行
            .anyRequest().authenticated()
            .and()
            .oauth2ResourceServer().jwt(); // 替换成你实际用的认证方式,比如JWT/用户名密码
    }
}
3. 最后检查几个常见坑
  • 确认token有效:如果本地存储的token过期或不存在,拦截器自然不会加头,这时候也会返回401,先去控制台看token是否存在。
  • 不要手动排除OPTIONS请求:有些同学会在拦截器里判断if (request.method !== 'OPTIONS')才加头,但其实后端已经配置放过OPTIONS了,即使OPTIONS没带Authorization也不会报错,反而手动排除可能导致逻辑混乱。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 18:37:32