namespace JWTdemo.Authorization; using Microsoft.Extensions.Options; using Microsoft.IdentityModel.Tokens; using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using System.Text; using JWTdemo.Entities; using JWTdemo.Helpers; public interface IJwtUtils { public string GenerateJwtToken(User user); public int? ValidateJwtToken(string? token); } public class JwtUtils : IJwtUtils { private readonly AppSettings _appSettings; public JwtUtils(IOptions appSettings) { _appSettings = appSettings.Value; if (string.IsNullOrEmpty(_appSettings.Secret)) throw new Exception("JWT secret not configured"); } public string GenerateJwtToken(User user) { // generate token that is valid for 7 days var tokenHandler = new JwtSecurityTokenHandler(); //實例化JWT令牌 var key = Encoding.ASCII.GetBytes(_appSettings.Secret!); //從配置中獲取應用程序密鑰,用於簽名令牌以確保其完整性和安全性 var tokenDescriptor = new SecurityTokenDescriptor //定義令牌格式,其包含header(SigningCredentials).payload(expires和subject).signature(簽在header裡面) { Subject = new ClaimsIdentity(new[] { new Claim("id", user.Id.ToString()) }), //payload Expires = DateTime.UtcNow.AddDays(7), //payload,令牌過期時間 SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature) //header }; var token = tokenHandler.CreateToken(tokenDescriptor); //創建JWT令牌 return tokenHandler.WriteToken(token); //將JWT令牌轉為base64編碼 } public int? ValidateJwtToken(string? token) { if (token == null) return null; var tokenHandler = new JwtSecurityTokenHandler(); var key = Encoding.ASCII.GetBytes(_appSettings.Secret!); try { tokenHandler.ValidateToken(token, new TokenValidationParameters { ValidateIssuerSigningKey = true, IssuerSigningKey = new SymmetricSecurityKey(key), ValidateIssuer = false, ValidateAudience = false, // set clockskew to zero so tokens expire exactly at token expiration time (instead of 5 minutes later) ClockSkew = TimeSpan.Zero }, out SecurityToken validatedToken); var jwtToken = (JwtSecurityToken)validatedToken; var userId = int.Parse(jwtToken.Claims.First(x => x.Type == "id").Value); // return user id from JWT token if validation successful return userId; } catch { // return null if validation fails return null; } } //0523 public bool ValidateToken(string token) { var tokenHandler = new JwtSecurityTokenHandler(); var jwtSecret = "your_jwt_secret"; // JWT 密钥,应与生成令牌时使用的密钥相匹配 var validationParameters = new TokenValidationParameters { ValidateIssuerSigningKey = true, IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSecret)), ValidateIssuer = false, ValidateAudience = false, ValidateLifetime = true, ClockSkew = TimeSpan.Zero // 设置为零以确保令牌过期时立即失效 }; try { SecurityToken validatedToken; tokenHandler.ValidateToken(token, validationParameters, out validatedToken); return true; } catch { return false; } } }