我实现了一个Github项目,不明白用户和Jwt的关键系统是如何工作的。现在,我有了一个位于AppSettings中的密钥,当用户登录时,将执行以下函数:
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添加后面的标头:
headers: {
'Content-type': 'application/json',
'Authorization': `Bearer ${sessionStorage.getItem("token")}`,
},
然后,它首先运行到以下函数:
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
}
}
因此,在这里,它验证来自token
的Header
不是null,然后尝试执行什么!?另外,为什么这里再次使用用户名?
当它运行ValidateToken
函数时,它返回一个错误: IDX12709: CanReadToken()返回false。JWT格式不佳:‘[ 'System.String’类型的PII是隐藏的‘
发布于 2022-01-26 22:01:18
JWT分为三个部分。第一个是具有加密算法等信息的报头。第二部分是有效载荷,在那里你可以找到你的索赔,在你的情况下,它将是一个用户名,执行日期,你可以在这里添加任何你需要的。这里添加了唯一的用户名或id,以便服务器知道这个令牌属于谁,以及谁在调用服务器。在另一种情况下,您将如何确定是谁在调用服务器,则必须将此令牌保存在某个数据库或与指定用户一起的某个地方。最后一部分是签名,这个部分是用你的秘密密钥来验证的,知道它不是一些假的令牌,实际上是你创建的一个令牌。零件被圆点分开。
很难说为什么您的令牌验证失败,一开始我会尝试在https://jwt.io上检查您创建的令牌,并查看其中的内容。也许您使用承载前缀验证令牌,因为它编写的令牌格式很差,所以可能是问题所在。
另外,您可以使用JWT默认身份验证方案,而不是使用自定义中间件auth。
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = false,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII
.GetBytes(Configuration.GetSection("AppSettings:Token").Value)),
//...
};
});
https://stackoverflow.com/questions/70870199
复制相似问题