#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;
}
}
}