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

.NET 8微服务项目中JWT令牌验证失败导致心跳接口401 Unauthorized问题排查

.NET 8微服务项目中JWT令牌验证失败导致心跳接口401 Unauthorized问题排查

首先看你给出的错误日志:IDX14100: JWT is not well formed, there are no dots (.),这个错误很明确——后端接收到的JWT格式不对,不是标准的三段式(Header.Payload.Signature)结构。结合你的描述,我帮你一步步排查:

第一步:确认前端实际发送的令牌是否正确

虽然你说localStorage.getItem("jwt")能拿到正确的令牌,但实际发送请求时可能出现意外。建议打开浏览器开发者工具的Network面板,找到POST /api/heartbeat的请求,查看Request Headers里的Authorization字段,确认是不是Bearer 后面跟着完整的、带两个点的JWT字符串。

常见的坑点:

  • 拼接Authorization头时出错:比如多打了空格、或者令牌被意外转义(比如带了引号)。你可以把前端代码改成模板字符串的写法,更清晰不易出错:
    async function sendHeartbeat() {
        const token = localStorage.getItem("jwt");
        console.log("Token:", token);
        if (!token) return;
        try {
            await fetch("/api/heartbeat", {
                method: "POST",
                headers: { 
                    "Authorization": `Bearer ${token}`,
                    "Content-Type": "application/json" // 可选,但如果接口需要,建议加上
                }
            });
        } catch (err) {
            console.error("Heartbeat failed:", err);
        }
    }
    

第二步:检查Nginx是否正确传递Authorization请求头

因为你用Nginx做反向代理,默认情况下Nginx可能不会传递一些自定义请求头,包括Authorization。你需要在Nginx的location配置块里显式添加:

location /api/heartbeat {
    proxy_pass http://your-hub-service-address;
    proxy_set_header Authorization $http_authorization;
    # 其他必要的代理配置,比如Host头
    proxy_set_header Host $host;
}

确保请求头完整传递到Hub服务,避免令牌被Nginx截断或丢失。

第三步:修正JWT验证配置的Issuer和Audience问题

虽然当前错误是格式问题,但即使格式修复后,你还会遇到新的验证失败——因为你生成JWT时没有指定Issuer和Audience,但Hub服务的验证配置里开启了ValidateIssuer = true和ValidateAudience = true,这会导致令牌因iss/aud不匹配被拒绝。

在Login服务中添加Issuer和Audience配置:

修改生成令牌的代码,从配置文件里读取Issuer和Audience:

var tokenDescriptor = new SecurityTokenDescriptor
{
    Subject = new ClaimsIdentity(new[] { new Claim(JwtRegisteredClaimNames.Name, loginRequest.Username) }),
    Expires = DateTime.UtcNow.AddHours(2),
    // 添加Issuer和Audience
    Issuer = config["Jwt:Issuer"],
    Audience = config["Jwt:Audience"],
    SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
};

在Hub服务中同步Issuer和Audience配置:

修改TokenValidationParameters,指定对应的有效值:

options.TokenValidationParameters = new TokenValidationParameters
{
    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtKey)),
    ValidateIssuer = true,
    ValidIssuer = builder.Configuration["Jwt:Issuer"], // 和Login服务一致
    ValidateAudience = true,
    ValidAudience = builder.Configuration["Jwt:Audience"], // 和Login服务一致
    ValidateLifetime = true,
    ValidateIssuerSigningKey = true,
};

第四步:确认两端的Jwt:Key完全一致

最后要确保Login服务和Hub服务使用的Jwt:Key是完全相同的——包括大小写、空格、特殊字符,因为SymmetricSecurityKey是基于字节数组验证的,哪怕一个字符差异都会导致签名验证失败。

按照以上步骤排查后,应该能解决当前的401问题。如果还是有问题,可以再检查Hub服务的OnAuthenticationFailed事件日志,看是否有新的错误提示。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 11:28:09