|
|
|
|
using DS.Module.Core.Extensions;
|
|
|
|
|
using Microsoft.IdentityModel.Tokens;
|
|
|
|
|
using System.IdentityModel.Tokens.Jwt;
|
|
|
|
|
using System.Security.Claims;
|
|
|
|
|
using System.Text;
|
|
|
|
|
|
|
|
|
|
namespace DS.Module.Core;
|
|
|
|
|
|
|
|
|
|
public class JwtHelper
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 生成JWT字符串
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="Jti"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public static string GetJWT(string Jti)
|
|
|
|
|
{
|
|
|
|
|
DateTime utc = DateTime.UtcNow;
|
|
|
|
|
string iss = AppSetting.app(new string[] { "JwtSettings", "Issuer" });
|
|
|
|
|
string aud = AppSetting.app(new string[] { "JwtSettings", "Audience" });
|
|
|
|
|
string secret = AppSetting.app(new string[] { "JwtSettings", "SecretKey" });
|
|
|
|
|
var claims = new List<Claim>
|
|
|
|
|
{
|
|
|
|
|
new Claim(JwtRegisteredClaimNames.Jti, Jti),
|
|
|
|
|
// 令牌颁发时间
|
|
|
|
|
new Claim(JwtRegisteredClaimNames.Iat, $"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}"),
|
|
|
|
|
new Claim(JwtRegisteredClaimNames.Nbf, $"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}"),
|
|
|
|
|
// 过期时间 2小时
|
|
|
|
|
new Claim(JwtRegisteredClaimNames.Exp,
|
|
|
|
|
$"{new DateTimeOffset(DateTime.Now).AddMinutes(120).ToUnixTimeSeconds()}"),
|
|
|
|
|
new Claim(JwtRegisteredClaimNames.Iss, iss), // 签发者
|
|
|
|
|
new Claim(JwtRegisteredClaimNames.Aud, aud) // 接收者
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 密钥
|
|
|
|
|
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secret));
|
|
|
|
|
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
|
|
|
|
|
var tokenHandler = new JwtSecurityTokenHandler();
|
|
|
|
|
JwtSecurityToken jwt = new JwtSecurityToken(
|
|
|
|
|
issuer: iss,
|
|
|
|
|
claims: claims, // 声明的集合
|
|
|
|
|
//expires: .AddSeconds(36), // token的有效时间
|
|
|
|
|
signingCredentials: creds
|
|
|
|
|
);
|
|
|
|
|
var handler = new JwtSecurityTokenHandler();
|
|
|
|
|
// 生成 jwt字符串
|
|
|
|
|
var strJWT = handler.WriteToken(jwt);
|
|
|
|
|
return strJWT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 生成Token
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="data"></param>
|
|
|
|
|
/// <param name="isRefresh">是否刷新</param>
|
|
|
|
|
/// <param name="isClient">是否客户端</param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public static string Encrypt(JwtTokenModel data, bool isRefresh = false,bool isClient = false)
|
|
|
|
|
{
|
|
|
|
|
DateTime utc = DateTime.UtcNow;
|
|
|
|
|
string iss = AppSetting.app(new string[] { "JwtSettings", "Issuer" });
|
|
|
|
|
string aud = AppSetting.app(new string[] { "JwtSettings", "Audience" });
|
|
|
|
|
string secret = AppSetting.app(new string[] { "JwtSettings", "SecretKey" });
|
|
|
|
|
var claims = new List<Claim>
|
|
|
|
|
{
|
|
|
|
|
new Claim(JwtRegisteredClaimNames.Jti, data.Uid),
|
|
|
|
|
// 令牌颁发时间
|
|
|
|
|
new Claim(JwtRegisteredClaimNames.Iat, $"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}"),
|
|
|
|
|
new Claim(JwtRegisteredClaimNames.Nbf, $"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}"),
|
|
|
|
|
// 过期时间 2小时
|
|
|
|
|
new Claim(JwtRegisteredClaimNames.Exp,
|
|
|
|
|
isRefresh
|
|
|
|
|
? $"{new DateTimeOffset(DateTime.Now).AddMinutes(150).ToUnixTimeSeconds()}" :$"{new DateTimeOffset(DateTime.Now).AddMinutes(120).ToUnixTimeSeconds()}"),
|
|
|
|
|
new Claim(JwtRegisteredClaimNames.Iss, iss), // 签发者
|
|
|
|
|
new Claim(JwtRegisteredClaimNames.Aud, aud), // 接收者
|
|
|
|
|
|
|
|
|
|
// new Claim("OrgId", data.OrgId), // 公司ID
|
|
|
|
|
new Claim("UserName", data.Name), // UserName
|
|
|
|
|
new Claim("TenantId", data.TenantId), // 租户ID
|
|
|
|
|
new Claim("TenantName", data.TenantName), // 租户名称
|
|
|
|
|
};
|
|
|
|
|
// 添加机构信息
|
|
|
|
|
if (isClient)
|
|
|
|
|
{
|
|
|
|
|
claims.Add(new Claim("OrgId", data.OrgId));// 机构ID
|
|
|
|
|
}
|
|
|
|
|
// 密钥
|
|
|
|
|
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secret));
|
|
|
|
|
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
|
|
|
|
|
var tokenHandler = new JwtSecurityTokenHandler();
|
|
|
|
|
JwtSecurityToken jwt = new JwtSecurityToken(
|
|
|
|
|
issuer: iss,
|
|
|
|
|
claims: claims, // 声明的集合
|
|
|
|
|
//expires: .AddSeconds(36), // token的有效时间
|
|
|
|
|
signingCredentials: creds
|
|
|
|
|
);
|
|
|
|
|
var handler = new JwtSecurityTokenHandler();
|
|
|
|
|
// 生成 jwt字符串
|
|
|
|
|
var strJWT = handler.WriteToken(jwt);
|
|
|
|
|
return strJWT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 解析
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="jwtStr"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public static string SerializeJwt(string jwtStr)
|
|
|
|
|
{
|
|
|
|
|
var jwtHandler = new JwtSecurityTokenHandler();
|
|
|
|
|
|
|
|
|
|
string userId = string.Empty;
|
|
|
|
|
// token校验
|
|
|
|
|
if (jwtStr.IsNullOrEmpty() && jwtHandler.CanReadToken(jwtStr))
|
|
|
|
|
{
|
|
|
|
|
JwtSecurityToken jwtToken = jwtHandler.ReadJwtToken(jwtStr);
|
|
|
|
|
userId = jwtToken.Claims.First().Value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return userId;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 对jwt字符串 解码
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static Dictionary<string, string> DecodeJwt(string accessToken)
|
|
|
|
|
{
|
|
|
|
|
Dictionary<string, string> dic = new Dictionary<string, string>();
|
|
|
|
|
var jwtHandler = new JwtSecurityTokenHandler();
|
|
|
|
|
// token校验
|
|
|
|
|
if (!string.IsNullOrEmpty(accessToken) && jwtHandler.CanReadToken(accessToken))
|
|
|
|
|
{
|
|
|
|
|
JwtSecurityToken jwtToken = jwtHandler.ReadJwtToken(accessToken);
|
|
|
|
|
var claims = jwtToken.Claims;
|
|
|
|
|
foreach (var claim in claims)
|
|
|
|
|
{
|
|
|
|
|
dic.Add(claim.Type, claim.Value);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return dic;
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// token实体
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class JwtTokenModel
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Id
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string Uid { get; set; }
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Name
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string Name { get; set; }
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// GID
|
|
|
|
|
/// </summary>
|
|
|
|
|
public Guid? GID { get; set; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 机构ID
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string OrgId { get; set; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 租户ID
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string TenantId { get; set; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 租户名称
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string TenantName { get; set; }
|
|
|
|
|
}
|
|
|
|
|
}
|