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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 08:01:06