首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Jwt令牌是如何工作和错误编码IDX12709的?

Jwt令牌是如何工作和错误编码IDX12709的?
EN

Stack Overflow用户
提问于 2022-01-26 21:00:33
回答 1查看 156关注 0票数 0

我实现了一个Github项目,不明白用户和Jwt的关键系统是如何工作的。现在,我有了一个位于AppSettings中的密钥,当用户登录时,将执行以下函数:

代码语言:javascript
运行
复制
private string GenerateJwtToken(string username)
{
   var tokenHandler = new JwtSecurityTokenHandler();
   var key = Encoding.ASCII.GetBytes(_appSettings.token);
   var tokenDescriptor = new SecurityTokenDescriptor
   {
      Subject = new ClaimsIdentity(new[] { new Claim("username", username) }), //<-
      Expires = DateTime.UtcNow.AddMinutes(30),
      SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
   };
   var token = tokenHandler.CreateToken(tokenDescriptor);
   return tokenHandler.WriteToken(token);
}

所以,如果我做对了,那么我在这里为登录的用户生成令牌,但是用户名的行意味着什么呢?在此之后,我将用户名和令牌存储在sessionStorage中,如果我触发了定义[Authorize]属性的其他Controller,则使用fetch添加后面的标头:

代码语言:javascript
运行
复制
headers: {
   'Content-type': 'application/json',
   'Authorization': `Bearer ${sessionStorage.getItem("token")}`,
},

然后,它首先运行到以下函数:

代码语言:javascript
运行
复制
public async Task Invoke(HttpContext context, IAuthService authService)
{
   var token = context.Request.Headers["Authorization"].FirstOrDefault()?.Split(" ").Last();
   if (token != null)
      attachUserToContext(context, authService, token);
   await _next(context);
}

private void attachUserToContext(HttpContext context, IAuthService authService, string token)
{
   try
   {
      var tokenHandler = new JwtSecurityTokenHandler();
      var key = Encoding.ASCII.GetBytes(_appSettings.Secret);
      tokenHandler.ValidateToken(token, new TokenValidationParameters //<- Error
      {
         ValidateIssuerSigningKey = true,
         IssuerSigningKey = new SymmetricSecurityKey(key),
         ValidateIssuer = false,
         ValidateAudience = false,
         ClockSkew = TimeSpan.Zero
      }, out SecurityToken validatedToken);
      var jwtToken = (JwtSecurityToken)validatedToken;
      var userId = int.Parse(jwtToken.Claims.First(x => x.Type == "username").Value);
      context.Items["User"] = "user";
   }
   catch
   {
      // do nothing if jwt validation fails
      // user is not attached to context so request won't have access to secure routes
   }
}

因此,在这里,它验证来自tokenHeader不是null,然后尝试执行什么!?另外,为什么这里再次使用用户名?

当它运行ValidateToken函数时,它返回一个错误: IDX12709: CanReadToken()返回false。JWT格式不佳:‘[ 'System.String’类型的PII是隐藏的‘

https://github.com/cornflourblue/dotnet-5-jwt-authentication-api/tree/279c8058669bbfa59902a4473f62e5371167340c

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-01-26 22:01:18

JWT分为三个部分。第一个是具有加密算法等信息的报头。第二部分是有效载荷,在那里你可以找到你的索赔,在你的情况下,它将是一个用户名,执行日期,你可以在这里添加任何你需要的。这里添加了唯一的用户名或id,以便服务器知道这个令牌属于谁,以及谁在调用服务器。在另一种情况下,您将如何确定是谁在调用服务器,则必须将此令牌保存在某个数据库或与指定用户一起的某个地方。最后一部分是签名,这个部分是用你的秘密密钥来验证的,知道它不是一些假的令牌,实际上是你创建的一个令牌。零件被圆点分开。

很难说为什么您的令牌验证失败,一开始我会尝试在https://jwt.io上检查您创建的令牌,并查看其中的内容。也许您使用承载前缀验证令牌,因为它编写的令牌格式很差,所以可能是问题所在。

另外,您可以使用JWT默认身份验证方案,而不是使用自定义中间件auth。

代码语言:javascript
运行
复制
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(options =>
            {
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = false,
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII
                        .GetBytes(Configuration.GetSection("AppSettings:Token").Value)),
                    //...
                };
            });
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70870199

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档