Jwt.cs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. using System.IdentityModel.Tokens.Jwt;
  2. using System.Security.Claims;
  3. using System.Text;
  4. using EasyTemplate.Tool.Entity;
  5. using Microsoft.IdentityModel.Tokens;
  6. using static EasyTemplate.Tool.Entity.PublicEnum;
  7. using JwtRegisteredClaimNames = Microsoft.IdentityModel.JsonWebTokens.JwtRegisteredClaimNames;
  8. namespace EasyTemplate.Tool;
  9. public class Jwt
  10. {
  11. /// <summary>
  12. /// 颁发JWT字符串
  13. /// </summary>
  14. /// <param name="tokenModel"></param>
  15. /// <returns></returns>
  16. public static string Serialize(TokenModelJwt tokenModel)
  17. {
  18. // 自己封装的 appsettign.json 操作类,看下文
  19. /*
  20. var iss = Appsettings.app("Audience", "Issuer");
  21. var aud = Appsettings.app("Audience", "Audience");
  22. var secret = Appsettings.app("Audience", "Secret");
  23. */
  24. var iss = "vue";
  25. var aud = "datacapture";
  26. var secret = "zhangminbianjibushujucaiji";
  27. var claims = new List<Claim>
  28. {
  29. /*
  30. * 特别重要:
  31. 1、这里将用户的部分信息,比如 uid 存到了Claim 中,如果你想知道如何在其他地方将这个 uid从 Token 中取出来,请看下边的SerializeJwt() 方法,或者在整个解决方案,搜索这个方法,看哪里使用了!
  32. 2、你也可以研究下 HttpContext.User.Claims ,具体的你可以看看 Policys/PermissionHandler.cs 类中是如何使用的。
  33. */
  34. new Claim(JwtRegisteredClaimNames.Name, tokenModel.Name),
  35. new Claim(JwtRegisteredClaimNames.Jti, tokenModel.UserId.ToString()),
  36. new Claim(JwtRegisteredClaimNames.Typ, ((int)tokenModel.UserType).ToString()),
  37. new Claim(JwtRegisteredClaimNames.Iat, $"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}"),
  38. new Claim(JwtRegisteredClaimNames.Nbf,$"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}") ,
  39. //这个就是过期时间,目前是过期秒,1天,可自定义,注意JWT有自己的缓冲过期时间
  40. new Claim (JwtRegisteredClaimNames.Exp,$"{new DateTimeOffset(DateTime.Now.AddSeconds(86400*7)).ToUnixTimeSeconds()}"),
  41. new Claim(JwtRegisteredClaimNames.Iss,iss),
  42. new Claim(JwtRegisteredClaimNames.Aud,aud),
  43. //new Claim(ClaimTypes.Role,tokenModel.Role),//为了解决一个用户多个角色(比如:Admin,System),用下边的方法
  44. };
  45. // 可以将一个用户的多个角色全部赋予;
  46. // 作者:DX 提供技术支持;
  47. //claims.AddRange(tokenModel.Grade.Split(',').Select(s => new Claim(ClaimTypes.Role, s)));
  48. claims.AddRange(tokenModel.Name.Split(',').Select(s => new Claim(ClaimTypes.Name, s)));
  49. //秘钥 (SymmetricSecurityKey 对安全性的要求,密钥的长度太短会报出异常)
  50. var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secret));
  51. var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
  52. var jwt = new JwtSecurityToken(
  53. issuer: iss,
  54. claims: claims,
  55. signingCredentials: creds);
  56. var jwtHandler = new JwtSecurityTokenHandler();
  57. var encodedJwt = jwtHandler.WriteToken(jwt);
  58. return encodedJwt;
  59. }
  60. /// <summary>
  61. /// 解析
  62. /// </summary>
  63. /// <param name="jwtStr"></param>
  64. /// <returns></returns>
  65. public static TokenModelJwt Deserialize(string jwtStr, out DateTime expired)
  66. {
  67. var jwtHandler = new JwtSecurityTokenHandler();
  68. var jwtToken = jwtHandler.ReadJwtToken(jwtStr);
  69. int type;
  70. object name;
  71. try
  72. {
  73. jwtToken.Payload.TryGetValue(ClaimTypes.Name, out name);
  74. jwtToken.Payload.TryGetValue(JwtRegisteredClaimNames.Typ, out object user_type);
  75. type = Convert.ToInt32(user_type);
  76. long exp = Convert.ToInt64(jwtToken.Payload["exp"]);
  77. expired = exp.ToDateTime();
  78. }
  79. catch (Exception e)
  80. {
  81. Console.WriteLine(e);
  82. throw;
  83. }
  84. var tm = new TokenModelJwt
  85. {
  86. UserId = int.Parse(jwtToken.Id),
  87. Name = name != null ? name.ToString() : "",
  88. UserType = (UserType)type
  89. };
  90. return tm;
  91. }
  92. }