using Microsoft.IdentityModel.Tokens; using System; using System.Collections.Generic; using System.IdentityModel.Tokens.Jwt; using System.Linq; using System.Security.Claims; using System.Text; using System.Threading.Tasks; using YuanXuan.IM.Common.Configs; using Microsoft.Extensions.Configuration; using System.Reflection; using System.IO; namespace YuanXuan.IM.Common.Helpers { public class JwtHelper { private static JwtSettings _jwtSettings; static JwtHelper() { // 初始化JWT配置 var configuration = new ConfigurationBuilder() .SetBasePath(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)) .AddJsonFile("appsettings.json", optional: true) .AddJsonFile("appsettings.Development.json", optional: true) .Build(); _jwtSettings = configuration.GetSection("Jwt").Get(); } /// /// 生成token /// /// /// /// /// /// /// /// public static string CreateToken(string uid, string secretKey, string issuer, string audience, double expires, List claims = null) { if (claims.IsNullOrEmpty()) claims = new(); claims.AddRange(new List { new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()), new Claim(ClaimTypes.NameIdentifier, uid), }); // 2. 从 appsettings.json 中读取SecretKey var secret = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey)); // 3. 选择加密算法 var algorithm = SecurityAlgorithms.HmacSha256; // 4. 生成Credentials var signingCredentials = new SigningCredentials(secret, algorithm); // 5. 根据以上,生成token var jwtSecurityToken = new JwtSecurityToken( issuer, //Issuer audience, //Audience claims, //Claims, DateTime.Now, //notBefore DateTime.Now.AddSeconds(expires), //expires signingCredentials //Credentials ); // 6. 将token变为string var token = new JwtSecurityTokenHandler().WriteToken(jwtSecurityToken); return token; } /// /// 生成JWT token /// /// /// /// public static string GenerateToken(string userId, string userName) { var claims = new List { new Claim(JwtRegisteredClaimNames.Sub, userId), new Claim(JwtRegisteredClaimNames.Name, userName), new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()) }; return CreateToken(userId, _jwtSettings.AccessSecret, _jwtSettings.Issuer, _jwtSettings.Audience, _jwtSettings.AccessExpiration); } /// /// 生成刷新token /// /// public static string GenerateRefreshToken() { return Guid.NewGuid().ToString("N"); } /// /// 从过期的token中获取principal /// /// /// public static ClaimsPrincipal GetPrincipalFromExpiredToken(string token) { var tokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidIssuer = _jwtSettings.Issuer, ValidateAudience = true, ValidAudience = _jwtSettings.Audience, ValidateIssuerSigningKey = true, IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtSettings.AccessSecret)), ValidateLifetime = false // 不验证过期时间 }; var tokenHandler = new JwtSecurityTokenHandler(); var principal = tokenHandler.ValidateToken(token, tokenValidationParameters, out var securityToken); if (!(securityToken is JwtSecurityToken jwtSecurityToken) || !jwtSecurityToken.Header.Alg.Equals(SecurityAlgorithms.HmacSha256, StringComparison.InvariantCultureIgnoreCase)) { throw new SecurityTokenException("无效的token"); } return principal; } } }