#region using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using System.Text; using Microsoft.IdentityModel.Tokens; using Web.Core.Model; #endregion namespace Web.Core.Common.Helper; public class JwtHelper { /// /// 颁发JWT字符串 /// /// /// public static string IssueJwt(TokenModel tokenModel) { //获取Appsetting配置 var iss = AppSettings.GetLogLevel("Jwt:Issuer"); var aud = AppSettings.GetLogLevel("Jwt:Audience"); var secret = AppSettings.GetLogLevel("Jwt:SecretKey"); var timeoutseconds = AppSettings.GetValue("Jwt:TimeOutSeconds", 1000); //var claims = new Claim[] //old var claims = new List { /* * 特别重要: 1、这里将用户的部分信息,比如 uid 存到了Claim 中,如果你想知道如何在其他地方将这个 uid从 Token 中取出来,请看下边的SerializeJwt() 方法,或者在整个解决方案,搜索这个方法,看哪里使用了! 2、你也可以研究下 HttpContext.User.Claims ,具体的你可以看看 Policys/PermissionHandler.cs 类中是如何使用的。 */ new(JwtRegisteredClaimNames.Jti, tokenModel.Uid.ToString()), new(JwtRegisteredClaimNames.Iat, $"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}"), new(JwtRegisteredClaimNames.Nbf, $"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}"), //这个就是过期时间,目前是过期1000秒,可自定义,注意JWT有自己的缓冲过期时间 new(JwtRegisteredClaimNames.Exp, $"{new DateTimeOffset(DateTime.Now.AddSeconds(timeoutseconds)).ToUnixTimeSeconds()}"), new(ClaimTypes.Expiration, DateTime.Now.AddSeconds(timeoutseconds).ToString()), new(JwtRegisteredClaimNames.Iss, iss), new(JwtRegisteredClaimNames.Aud, aud) }; // 可以将一个用户的多个角色全部赋予; claims.AddRange(tokenModel.Role.Split(',').Select(s => new Claim(ClaimTypes.Role, s))); //秘钥 (SymmetricSecurityKey 对安全性的要求,密钥的长度太短会报出异常) var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secret)); var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); var jwt = new JwtSecurityToken( iss, claims: claims, signingCredentials: creds); var jwtHandler = new JwtSecurityTokenHandler(); var encodedJwt = jwtHandler.WriteToken(jwt); return encodedJwt; } /// /// 解析 /// /// /// public static TokenModel SerializeJwt(string jwtStr) { if (jwtStr == null) { return null; } jwtStr = jwtStr.Replace("Bearer ", ""); var jwtHandler = new JwtSecurityTokenHandler(); var jwtToken = jwtHandler.ReadJwtToken(jwtStr); var claims = jwtToken.Payload.Claims; var res1 = jwtToken.Payload.TryGetValue(ClaimTypes.Role, out var role); if (res1) { return new TokenModel { Uid = claims.First(c => c.Type == "jti")?.Value ?? "", Role = role == null ? "" : role.ToString() }; } else { return null; } } }