Files
QYZH.InteractiveMagazine/QYZH.InteractiveMagazine.Infrastructure/Auth/JwtHelper.cs
glz b95c5029f1 feat: 添加期刊二维码管理功能,调整UserJournal的UserId为可空类型
1.  新增数据库脚本修改User表UserId字段为可空
2.  新增期刊二维码CRUD接口与控制器
3.  重构绑定期刊逻辑,优化重复绑定校验
4.  删除冗余的JwtHelper重载方法
2026-07-01 17:05:38 +08:00

165 lines
5.6 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.

using Microsoft.IdentityModel.Tokens;
using QYZH.InteractiveMagazine.Models.Settings;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
namespace QYZH.InteractiveMagazine.Infrastructure.Auth;
/// <summary>
/// JWT工具类
/// </summary>
public static class JwtHelper
{
public const string AdminTokenKeyPrefix = "InteractiveMagazine:AdminAuth:Token";
public const string WeChatTokenKeyPrefix = "InteractiveMagazine:WeChatAuth:Token";
/// <summary>
/// 生成JWT令牌管理端 / 单用户场景)
/// </summary>
/// <param name="userId">用户ID</param>
/// <param name="userName">用户名</param>
/// <param name="settings">JWT配置</param>
/// <returns>JWT令牌字符串</returns>
public static string GenerateToken(long userId, string userName, JwtSettings settings)
{
var claims = new[]
{
new Claim(JwtRegisteredClaimNames.Sub, userId.ToString()),
new Claim(JwtRegisteredClaimNames.Name, userName),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
new Claim(ClaimTypes.NameIdentifier, userId.ToString()),
new Claim(ClaimTypes.Name, userName)
};
return BuildToken(claims, settings);
}
/// <summary>
/// 生成JWT令牌小程序场景同时携带 WxUserId 和 UserId
/// </summary>
/// <param name="wxUserId">微信用户IDWxUser.Id</param>
/// <param name="userId">当前激活用户IDUsers.Id无用户时为 0</param>
/// <param name="userName">用户名</param>
/// <param name="settings">JWT配置</param>
/// <returns>JWT令牌字符串</returns>
public static string GenerateToken(long wxUserId, long userId, string userName, JwtSettings settings)
{
var claims = new[]
{
new Claim(JwtRegisteredClaimNames.Sub, userId.ToString()),
new Claim(JwtRegisteredClaimNames.Name, userName),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
new Claim(ClaimTypes.NameIdentifier, userId.ToString()),
new Claim(ClaimTypes.Name, userName),
new Claim(WxUserIdClaimType, wxUserId.ToString())
};
return BuildToken(claims, settings);
}
/// <summary>
/// 自定义 Claim 类型WxUserId
/// </summary>
public const string WxUserIdClaimType = "WxUserId";
public static string BuildAdminTokenKey(string userId)
{
return $"{AdminTokenKeyPrefix}:{userId}";
}
public static string BuildWeChatTokenKey(string wxUserId, string userId)
{
return $"{WeChatTokenKeyPrefix}:{wxUserId}:{userId}";
}
public static string BuildWeChatTokenKey(long wxUserId, long userId)
{
return BuildWeChatTokenKey(wxUserId.ToString(), userId.ToString());
}
private static string BuildToken(Claim[] claims, JwtSettings settings)
{
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(settings.SecretKey!));
var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken(
issuer: settings.Issuer,
audience: settings.Audience,
claims: claims,
expires: DateTime.Now.AddDays(settings.JwtTokenExpiryDays),
signingCredentials: credentials
);
return new JwtSecurityTokenHandler().WriteToken(token);
}
/// <summary>
/// 获取Token过期时间
/// </summary>
/// <param name="token">JWT令牌</param>
/// <returns>过期时间</returns>
public static DateTime? GetTokenExpiry(string token)
{
var tokenHandler = new JwtSecurityTokenHandler();
if (tokenHandler.ReadToken(token) is JwtSecurityToken jwtToken)
{
return jwtToken.ValidTo;
}
return null;
}
/// <summary>
/// 从Token中获取用户ID
/// </summary>
/// <param name="token">JWT令牌</param>
/// <returns>用户ID</returns>
public static long? GetUserIdFromToken(string token)
{
var tokenHandler = new JwtSecurityTokenHandler();
if (tokenHandler.ReadToken(token) is JwtSecurityToken jwtToken)
{
var userIdClaim = jwtToken.Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier);
if (long.TryParse(userIdClaim?.Value, out long userId))
{
return userId;
}
}
return null;
}
/// <summary>
/// 从Token中获取微信用户IDWxUserId
/// </summary>
/// <param name="token">JWT令牌</param>
/// <returns>WxUserId</returns>
public static long? GetWxUserIdFromToken(string token)
{
var tokenHandler = new JwtSecurityTokenHandler();
if (tokenHandler.ReadToken(token) is JwtSecurityToken jwtToken)
{
var wxUserIdClaim = jwtToken.Claims.FirstOrDefault(c => c.Type == WxUserIdClaimType);
if (long.TryParse(wxUserIdClaim?.Value, out long wxUserId))
{
return wxUserId;
}
}
return null;
}
/// <summary>
/// 从Token中获取用户名
/// </summary>
/// <param name="token">JWT令牌</param>
/// <returns>用户名</returns>
public static string GetUserNameFromToken(string token)
{
var tokenHandler = new JwtSecurityTokenHandler();
if (tokenHandler.ReadToken(token) is JwtSecurityToken jwtToken)
{
return jwtToken.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Name)?.Value ?? string.Empty;
}
return string.Empty;
}
}