Angular 4+ASP.NET Core 2.0使用JWT遇CORS相关401错误求助
我之前也碰到过几乎一模一样的问题——Angular 4 + ASP.NET Core 2.0跨域带JWT令牌请求返回401,折腾了好几天才搞定,给你几个排查和解决的关键点:
1. 先排查ASP.NET Core端的CORS配置顺序
这是最容易踩坑的地方!浏览器发送带自定义头(比如Authorization)的请求时,会先发OPTIONS预检请求,如果后端的中间件顺序不对,预检请求会被认证逻辑直接拦截返回401,真实请求根本没机会发送。
正确的配置顺序必须是:UseCors() → UseAuthentication() → UseMvc(),并且一定要开启AllowCredentials()。给你参考完整的Startup配置:
// ConfigureServices方法中先注册CORS服务 public void ConfigureServices(IServiceCollection services) { // 注册CORS services.AddCors(); // 注册JWT认证 services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ValidIssuer = "你的Issuer", ValidAudience = "你的Audience", IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("你的签名密钥")) }; // 关键:让JWT中间件跳过OPTIONS预检请求的认证 options.Events = new JwtBearerEvents { OnMessageReceived = context => { if (context.Request.Method == HttpMethod.Options.Method) { context.Response.StatusCode = (int)HttpStatusCode.OK; return Task.CompletedTask; } return Task.CompletedTask; } }; }); services.AddMvc(); } // Configure方法中按顺序启用中间件 public void Configure(IApplicationBuilder app, IHostingEnvironment env) { // 异常处理等中间件... // 启用CORS,必须在认证和MVC之前 app.UseCors(builder => builder .WithOrigins("http://localhost:4200") // 替换成你的Angular端口,别用AllowAnyOrigin(和AllowCredentials冲突) .AllowAnyMethod() .AllowAnyHeader() .AllowCredentials()); // 带Authorization头的请求必须开启这个 // 启用认证 app.UseAuthentication(); // 启用MVC app.UseMvc(); }
2. 检查Angular端的请求配置
确保请求头格式正确,并且开启withCredentials对应后端的配置:
import { HttpClient, HttpHeaders } from '@angular/common/http'; @Injectable() export class DataService { constructor(private http: HttpClient) {} fetchProtectedData() { const token = localStorage.getItem('jwt-token'); const headers = new HttpHeaders({ 'Authorization': `Bearer ${token}` // 注意Bearer后面有个空格!别漏了 }); return this.http.get('http://你的API地址/api/protected', { headers, withCredentials: true // 和后端的AllowCredentials对应 }); } }
3. 排查令牌本身的有效性
有时候401和CORS无关,是令牌本身有问题:
- 用jwt.io解码令牌,检查
exp字段是否过期 - 确认令牌的
iss、aud和后端配置的一致 - 检查签名密钥是否和后端完全匹配(大小写、特殊字符都不能错)
4. 抓包分析请求细节
用Chrome DevTools的Network面板或者Fiddler抓包:
- 看是否先发了OPTIONS请求,响应状态码是不是200?如果OPTIONS返回401,肯定是后端CORS中间件顺序或配置错了
- 如果OPTIONS正常,再看真实请求的Request Headers里有没有
Authorization字段,值是不是Bearer <你的令牌> - 查看后端日志,确认是否接收到令牌,以及令牌验证失败的具体原因
我当时就是把UseCors()放在了UseAuthentication()之后,导致OPTIONS预检请求被认证拦截,调整顺序后问题直接解决。另外一定要记得开启AllowCredentials(),否则浏览器会主动拒绝发送带Authorization头的请求。
内容的提问来源于stack exchange,提问作者Arsiwaldi
相关产品推荐
相关产品推荐

