侧边栏壁纸
博主头像
分享你我博主等级

行动起来,活在当下

  • 累计撰写 107 篇文章
  • 累计创建 13 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

asp .net core jwt 帮助类 JwtHelper

管理员
2020-09-17 / 0 评论 / 0 点赞 / 4 阅读 / 24442 字
 /// <summary>
    /// Jwt帮助类
    /// </summary>
    public static class JwtHelper
    {
        private static JwtSettings settings;
        public static JwtSettings Settings { set { settings = value; } get { return settings; } }
        /// <summary>
        /// 生成token
        /// </summary>
        /// <param name="claims"></param>
        /// <returns></returns>
        public static string CreateToken(IEnumerable<Claim> claims)
        {
            SymmetricSecurityKey key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(settings.SecurityKey));
            //证书
            SigningCredentials credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
            var securityToken = new JwtSecurityToken(
                issuer: settings.Issuer,//JWT的签发者
                audience: settings.Audience,//接收JWT的一方
                claims: claims,//自定义用户值
                expires: DateTime.Now.AddMinutes(settings.ExpMinutes),//什么时候过期
                signingCredentials: credentials //证书
                );
            var token = new JwtSecurityTokenHandler().WriteToken(securityToken);
            return token;
        }
        /// <summary>
        /// 生成Jwt
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="roleName"></param>
        /// <param name="userId"></param>
        /// <returns></returns>
        public static string CreateToken(string userName, string roleId, string userId)
        {
            //声明claim
            var claims = new Claim[] {
                new Claim(JwtRegisteredClaimNames.Sub, userName),
                new Claim(JwtRegisteredClaimNames.Jti, userId),
                new Claim(JwtRegisteredClaimNames.Iat,DateTimeOffset.Now.ToUnixTimeMilliseconds().ToString(), ClaimValueTypes.Integer64),//签发时间
                new Claim(JwtRegisteredClaimNames.Nbf, DateTimeOffset.Now.ToUnixTimeMilliseconds().ToString(), ClaimValueTypes.Integer64),//生效时间
                new Claim(JwtRegisteredClaimNames.Exp,DateTimeOffset.Now.AddMinutes(settings.ExpMinutes).ToUnixTimeMilliseconds().ToString(), ClaimValueTypes.Integer64), //过期时间
                new Claim(JwtRegisteredClaimNames.Iss, settings.Issuer),
                new Claim(JwtRegisteredClaimNames.Aud, settings.Audience),
                new Claim(ClaimTypes.Name, userName),
                new Claim(ClaimTypes.Role, roleId),
                new Claim(ClaimTypes.Sid, userId),
            };
            return CreateToken(claims);
        }
        /// <summary>
        /// 刷新token
        /// </summary>
        /// <returns></returns>
        public static string RefreshToken(string oldToken)
        {
            var pl = GetPayload(oldToken);
            //声明claim
            var claims = new Claim[] {
                new Claim(JwtRegisteredClaimNames.Sub, pl?.UserName),
                new Claim(JwtRegisteredClaimNames.Jti, pl?.UserId),
                new Claim(JwtRegisteredClaimNames.Iat,DateTimeOffset.Now.ToUnixTimeMilliseconds().ToString(), ClaimValueTypes.Integer64),//签发时间
                new Claim(JwtRegisteredClaimNames.Nbf, DateTimeOffset.Now.ToUnixTimeMilliseconds().ToString(), ClaimValueTypes.Integer64),//生效时间
                new Claim(JwtRegisteredClaimNames.Exp, DateTimeOffset.Now.AddMinutes(settings.ExpMinutes).ToUnixTimeMilliseconds().ToString(), ClaimValueTypes.Integer64), //过期时间
                new Claim(JwtRegisteredClaimNames.Iss, settings.Issuer),
                new Claim(JwtRegisteredClaimNames.Aud, settings.Audience),
                new Claim(ClaimTypes.Name, pl?.UserName),
                new Claim(ClaimTypes.Role, pl?.RoleId),
                new Claim(ClaimTypes.Sid, pl?.UserId)
            };
            return IsExp(oldToken) ? CreateToken(claims) : null;
        }
        /// <summary>
        /// 从token中获取用户身份
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        public static IEnumerable<Claim> GetClaims(string token)
        {
            var handler = new JwtSecurityTokenHandler();
            var securityToken = handler.ReadJwtToken(token);
            return securityToken?.Claims;
        }
        /// <summary>
        /// 从Token中获取用户身份
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        public static ClaimsPrincipal GetPrincipal(string token)
        {
            var handler = new JwtSecurityTokenHandler();
            try
            {
                return handler.ValidateToken(token, new TokenValidationParameters
                {
                    ValidateAudience = false,
                    ValidateIssuer = false,
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(settings.SecurityKey)),
                    ValidateLifetime = false
                }, out SecurityToken validatedToken);
            }
            catch (Exception)
            {
                return null;
            }
        }
        /// <summary>
        /// 校验Token
        /// </summary>
        /// <param name="token">token</param>
        /// <returns></returns>
        public static bool CheckToken(string token)
        {
            var principal = GetPrincipal(token);
            if (principal is null)
            {
                return false;
            }
            return true;
        }
        /// <summary>
        /// 获取Token中的载荷数据
        /// </summary>
        /// <param name="token">token</param>
        /// <returns></returns>
        public static JwtPayload GetPayload(string token)
        {
            var jwtHandler = new JwtSecurityTokenHandler();
            JwtSecurityToken securityToken = jwtHandler.ReadJwtToken(token);
            return new JwtPayload
            {
                UserId = securityToken.Id,
                UserName = securityToken.Payload[JwtRegisteredClaimNames.Sub]?.ToString(),
                RoleId = (securityToken.Payload[ClaimTypes.Role] ?? 0).ToString(),
                ExpTime = Convert.ToInt64(securityToken.Payload[JwtRegisteredClaimNames.Exp])
            };
        }
        /// <summary>
        /// 获取Token中的载荷数据
        /// </summary>
        /// <typeparam name="T">泛型</typeparam>
        /// <param name="token">token</param>
        /// <returns></returns>
        public static T GetPayload<T>(string token)
        {
            var jwtHandler = new JwtSecurityTokenHandler();
            JwtSecurityToken jwtToken = jwtHandler.ReadJwtToken(token);
            return JsonConvert.DeserializeObject<T>(jwtToken.Payload.SerializeToJson());
        }
        /// <summary>
        /// 判断token是否过期
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        public static bool IsExp(string token)
        {
            return Convert.ToDateTime(GetPrincipal(token)?.Claims.First(c => c.Type == JwtRegisteredClaimNames.Exp)?.Value) < DateTime.Now;
            //return GetPayload(token).ExpTime < DateTime.Now;
        }
        #region 从上下文请求流操作
        /// <summary>
        /// 判断是否为AJAX请求
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        public static bool IsAjaxRequest(HttpRequest req)
        {
            bool result = false;
            var xreq = req.Headers.ContainsKey("x-requested-with");
            if (xreq)
            {
                result = req.Headers["x-requested-with"] == "XMLHttpRequest";
            }
            return result;
        }
        /// <summary>
        /// 获取Token
        /// </summary>
        /// <param name="req">请求流</param>
        /// <returns></returns>
        public static string GetToken(HttpRequest req)
        {
            string tokenHeader = req.Headers["Authorization"].ToString();
            if (string.IsNullOrEmpty(tokenHeader))
                throw new Exception("缺少token!");
            string pattern = "^Bearer (.*?)$";
            if (!Regex.IsMatch(tokenHeader, pattern))
                throw new Exception("token格式不对!格式为:Bearer {token}");
            string token = Regex.Match(tokenHeader, pattern).Groups[1]?.ToString();
            if (string.IsNullOrEmpty(token))
                throw new Exception("token不能为空!");
            return token;
        }
        #endregion
    }
    //iss: jwt签发者
    //sub: jwt所面向的用户
    //aud: 接收jwt的一方
    //exp: jwt的过期时间,这个过期时间必须要大于签发时间
    //nbf: 定义在什么时间之前,该jwt都是不可用的.
    //iat: jwt的签发时间
    //jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。
    //var jwt_id = User.Claims.FirstOrDefault(p => p.Type == "jti").Value;
    //User.Claims.Select(p => new { p.Type, p.Value
    /// <summary>
    /// Jwt设置
    /// </summary>
    public class JwtSettings
    {
        /// <summary>
        /// 发行人
        /// </summary>
        public string Issuer { get; set; }
        /// <summary>
        /// 订阅者
        /// </summary>
        public string Audience { get; set; }
        /// <summary>
        /// 加密key
        /// </summary>
        public string SecurityKey { get; set; }
        /// <summary>
        /// 过期分钟
        /// </summary>
        public int ExpMinutes { get; set; }
    }
    /// <summary>
    /// Jwt载荷信息
    /// </summary>
    public class JwtPayload
    {
        public string UserId { get; set; }
        public string UserName { get; set; }
        public string RealName { get; set; }
        public string RoleId { get; set; }
        public long ExpTime { get; set; }
    }


0

评论区