Backend/C_shape/WEBAPI/JWT/JWTdemo/Authorization/JwtUtils.cs
Lin Weiting c07b6c1706 JWT
2024-05-06 14:09:39 +08:00

106 lines
3.7 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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