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

ASP.NET 6拒绝jsonwebtoken生成的JWT,请求返回401求助

ASP.NET 6无法验证TypeScript生成JWT的401问题排查

我有两台服务器,一台用TypeScript的jsonwebtoken库生成JWT,另一台运行ASP.NET 6。请求时通过Authorization: Bearer token_value头携带JWT,但始终收到401错误,疑惑JWT通用却只能验证自身生成的Token,求问题原因。

TypeScript生成JWT的代码

import jwt from "jsonwebtoken"

const payload = {
    iss: "identity.example.com",
    exp: getTimeNow() + 5 * 60 * 1000,
    sub: account.user_id,
    aud: "store.example.com",
    exc: item.id
}

res.status(200).json({
    code: 200,
    message: "",
        data: {
            jwt: jwt.sign(payload, process.env.JWT_SIGNING_KEY!, {
            algorithm: "HS256"
        })
    }
})

ASP.NET 6的Program.cs配置

using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>
{
    options.TokenValidationParameters = new TokenValidationParameters()
    {
        ValidateIssuer = true,
        ValidateAudience = true,
        ValidateLifetime = true,
        ValidateIssuerSigningKey = true,
        ValidIssuer = "identity.example.com",
        ValidAudience = "store.example.com",
        IssuerSigningKey = new SymmetricSecurityKey(System.Text.Encoding.UTF8.GetBytes("KEY"))
    };
});

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();

app.Run();

问题原因排查及解决方法

  • 时间戳单位不匹配(最可能的原因)
    jsonwebtoken库要求exp字段为秒级Unix时间戳,但你的代码使用了毫秒级时间(getTimeNow() + 5*60*1000)。ASP.NET Core默认解析秒级时间戳,这会导致Token刚生成就被判定为过期,直接返回401。
    解决方法:将exp改为秒级时间戳:

    exp: Math.floor(Date.now() / 1000) + 5 * 60,
    
  • 签名密钥一致性问题
    确认TypeScript端的process.env.JWT_SIGNING_KEY与ASP.NET端的"KEY"完全一致,无前后空格、特殊字符转义差异。两边均使用UTF-8编码处理密钥,这点配置没问题,但需确保密钥本身无差异。

  • 开启验证日志定位具体错误
    如果上述两点排查无误,可开启JWTBearer详细日志查看失败原因。在ASP.NET的appsettings.Development.json中添加配置:

    {
      "Logging": {
        "LogLevel": {
          "Microsoft.AspNetCore.Authentication.JwtBearer": "Debug"
        }
      }
    }
    

    运行后日志会明确提示是签名不匹配、受众/发行者错误还是生命周期验证失败。

  • 自定义Claim的潜在影响
    payload中的exc是自定义Claim,ASP.NET Core默认不影响验证,但如果控制器或中间件对Claim有额外校验,可能导致401。可先移除该字段测试是否能正常验证。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 04:53:22