最近准备把一些外部认证接口认证改成jwt的,在 jwt.io的网站上找了下,.net的库中排名第一的是微软自家的库System.IdentityModel.Tokens.Jwt,然而官方文档对如何使用它却语焉不详,今天试了一下如何用这个微软官方的JWT库。简单的写个文章总结下
这个库的核心对象是JwtSecurityTokenHandler,可以通过它实现JWT的生成,读取,校验等核心操作,下面就以几个简单的示例演示下:
生成Token
生成token需要使用JwtSecurityTokenHandler.CreateToken函数,这里使用的key函数比较简单,直接读的ASCII码,传入的时候需要保持和密码算法要求位数一致,实际使用时可以进行响应的修改。
public string GenerateToken(string id, string secret) { var tokenHandler = new JwtSecurityTokenHandler(); var key = Encoding.ASCII.GetBytes(secret); var tokenDescriptor = new SecurityTokenDescriptor { Subject = new ClaimsIdentity(new[] { new Claim("id", id) }), Expires = DateTime.UtcNow.AddDays(7), SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature) }; var token = tokenHandler.CreateToken(tokenDescriptor); return tokenHandler.WriteToken(token); }
读取Token
读取token需要使用JwtSecurityTokenHandler.ReadToken函数,基本示例如下,由于读取的是明文部分,故是不需要传输密码的。
public void ReadToken(string token) { var tokenHandler = new JwtSecurityTokenHandler(); var readedToken = tokenHandler.ReadToken(token); var jwtToken = (JwtSecurityToken)readedToken; //读取id var userId = jwtToken.Claims.First(x => x.Type == "id").Value; }
校验Token
读取token需要使用JwtSecurityTokenHandler. ValidateToken函数,可以传入多个校验参数,时间,密码等,时间也支持容差,算是功能比较全了。
public void ValidateToken(string token, string secret) { var tokenHandler = new JwtSecurityTokenHandler(); var key = Encoding.ASCII.GetBytes(secret); tokenHandler.ValidateToken(token, new TokenValidationParameters { ValidateIssuerSigningKey = true, IssuerSigningKey = new SymmetricSecurityKey(key), ValidateIssuer = false, ValidateAudience = false, }, out SecurityToken validatedToken); var jwtToken = (JwtSecurityToken)validatedToken; //读取id var userId = jwtToken.Claims.First(x => x.Type == "id").Value; }
最后,值得一提的是,这个库对key有最小长度要求的,但有一些库是可以使用短密码的,如果要兼容那些短密码,可对key后补0,补齐到相应长度即可。
参考文章:
.NET 5.0 - Create and Validate JWT Tokens + Use Custom JWT Middleware