104 lines
4.1 KiB
C#
104 lines
4.1 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.IdentityModel.Tokens.Jwt;
|
||
using System.Security.Claims;
|
||
using System.Text;
|
||
using Microsoft.Extensions.Options;
|
||
using Microsoft.IdentityModel.Tokens;
|
||
using ZhiZhun.AuthenticationCenter.User;
|
||
|
||
namespace ZhiZhun.AuthenticationCenter.Utility
|
||
{
|
||
/// <summary>
|
||
/// 对称可逆加密
|
||
/// </summary>
|
||
public class JWTHSService : IJWTService
|
||
{
|
||
private static Dictionary<string, UserBasicInfo> TokenCache = new Dictionary<string, UserBasicInfo>();
|
||
|
||
#region Option注入
|
||
private readonly JWTTokenOptions _JWTTokenOptions;
|
||
public JWTHSService(IOptionsMonitor<JWTTokenOptions> jwtTokenOptions)
|
||
{
|
||
this._JWTTokenOptions = jwtTokenOptions.CurrentValue;
|
||
}
|
||
#endregion
|
||
|
||
public string GetToken(UserBasicInfo userModel)
|
||
{
|
||
return this.IssueToken(userModel);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 刷新token的有效期问题上端校验
|
||
/// </summary>
|
||
/// <param name="refreshToken"></param>
|
||
/// <returns></returns>
|
||
public string GetTokenByRefresh(string refreshToken)
|
||
{
|
||
if (TokenCache.ContainsKey(refreshToken))
|
||
{
|
||
string token = this.IssueToken(TokenCache[refreshToken], 60);
|
||
return token;
|
||
}
|
||
else
|
||
{
|
||
return "";
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 2个token 就是有效期不一样
|
||
/// </summary>
|
||
/// <param name="userInfo"></param>
|
||
/// <returns></returns>
|
||
public Tuple<string, string> GetTokenWithRefresh(UserBasicInfo userInfo)
|
||
{
|
||
string token = this.IssueToken(userInfo, 60);//1分钟
|
||
string refreshToken = this.IssueToken(userInfo, 60 * 60 * 24);//24小时
|
||
TokenCache.Add(refreshToken, userInfo);
|
||
|
||
return Tuple.Create(token, refreshToken);
|
||
}
|
||
|
||
/**
|
||
* Claims (Payload)
|
||
Claims 部分包含了一些跟这个 token 有关的重要信息。 JWT 标准规定了一些字段,下面节选一些字段:
|
||
iss: The issuer of the token,token 是给谁的
|
||
sub: The subject of the token,token 主题
|
||
exp: Expiration Time。 token 过期时间,Unix 时间戳格式
|
||
iat: Issued At。 token 创建时间, Unix 时间戳格式
|
||
jti: JWT ID。针对当前 token 的唯一标识
|
||
除了规定的字段外,可以包含其他任何 JSON 兼容的字段。
|
||
* */
|
||
private string IssueToken(UserBasicInfo user, int second = 600)
|
||
{
|
||
var claims = new[]
|
||
{
|
||
new Claim(Microsoft.IdentityModel.JsonWebTokens.JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
|
||
new Claim("id", user.Id.ToString()),
|
||
new Claim("name", user.UserName),
|
||
new Claim("realName", user.RealName),
|
||
new Claim("reviewerCode",user.ReviewerCode),
|
||
new Claim("userTypeEnumName",user.UserTypeEnum.ToString()),
|
||
new Claim("userTypeEnumInt",((int)user.UserTypeEnum).ToString()),
|
||
new Claim("userTypeShortName",user.UserTypeShortName),
|
||
new Claim("isAdmin",(user.UserTypeEnum==UserType.SuperAdmin).ToString())
|
||
};
|
||
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(this._JWTTokenOptions.SecurityKey));
|
||
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
|
||
|
||
|
||
var token = new JwtSecurityToken(
|
||
issuer: this._JWTTokenOptions.Issuer,
|
||
audience: this._JWTTokenOptions.Audience,
|
||
claims: claims,
|
||
expires: DateTime.Now.AddSeconds(second),//10分钟有效期
|
||
notBefore: null,//立即生效 DateTime.Now.AddMilliseconds(30),//30s后有效
|
||
signingCredentials: creds);
|
||
string returnToken = new JwtSecurityTokenHandler().WriteToken(token);
|
||
return returnToken;
|
||
}
|
||
}
|
||
}
|