天天看點

jwt token 過期重新整理_.net core 3.1 Jwt操作封裝類,JwtHelper,支援生成、重新整理等

最近在開發項目中,為了便于操作jwt,自己封裝了一個jwthelper,發出來,供大家一起讨論。

jwt token 過期重新整理_.net core 3.1 Jwt操作封裝類,JwtHelper,支援生成、重新整理等
using Microsoft.AspNetCore.Http;using Microsoft.IdentityModel.Tokens;using Newtonsoft.Json;using System;using System.Collections.Generic;using System.IdentityModel.Tokens.Jwt;using System.Linq;using System.Security.Claims;using System.Text;using System.Text.RegularExpressions;using TianFeng.FrameworkCore.Extensions;namespace TFCMS.Tools{    //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    ///     /// Jwt設定    ///     public class JwtSettings    {        ///         /// 發行人        ///         public string Issuer { get; set; }        ///         /// 訂閱者        ///         public string Audience { get; set; }        ///         /// 加密key        ///         public string SecurityKey { get; set; }        ///         /// 過期分鐘        ///         public int ExpMinutes { get; set; }    }    ///     /// Jwt載荷資訊    ///     public class JwtPayload    {        public string UserId { get; set; }        public string UserName { get; set; }        public string RoleId { get; set; }        public DateTime ExpTime { get; set; }    }    ///     /// Jwt幫助類    ///     public static class JwtHelper    {        private static JwtSettings settings;        public static JwtSettings Settings { set { settings = value; } get { return settings; } }        ///         /// 生成token        ///         ///         ///         public static string CreateToken(IEnumerable claims)        {            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(settings.SecurityKey));            var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);            var securityToken = new JwtSecurityToken(                issuer: settings.Issuer,                audience: settings.Audience,                claims: claims,                //expires: DateTime.Now.AddMinutes(settings.ExpMinutes),                signingCredentials: creds);            var token = new JwtSecurityTokenHandler().WriteToken(securityToken);            return token;        }        ///         /// 生成Jwt        ///         ///         ///         ///         ///         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, DateTime.UtcNow.ToUnixDate().ToString(), ClaimValueTypes.Integer64),//簽發時間                new Claim(JwtRegisteredClaimNames.Nbf, DateTime.UtcNow.ToUnixDate().ToString(), ClaimValueTypes.Integer64),//生效時間                new Claim(JwtRegisteredClaimNames.Exp, DateTime.Now.AddMinutes(settings.ExpMinutes).ToUnixDate().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);        }        ///         /// 重新整理token        ///         ///         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, DateTime.UtcNow.ToUnixDate().ToString(), ClaimValueTypes.Integer64),//簽發時間                new Claim(JwtRegisteredClaimNames.Nbf, DateTime.UtcNow.ToUnixDate().ToString(), ClaimValueTypes.Integer64),//生效時間                new Claim(JwtRegisteredClaimNames.Exp, DateTime.Now.AddMinutes(settings.ExpMinutes).ToUnixDate().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;        }        ///         /// 從token中擷取使用者身份        ///         ///         ///         public static IEnumerable GetClaims(string token)        {            var handler = new JwtSecurityTokenHandler();            var securityToken = handler.ReadJwtToken(token);            return securityToken?.Claims;        }        ///         /// 從Token中擷取使用者身份        ///         ///         ///         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;            }        }        ///         /// 校驗Token        ///         /// token        ///         public static bool CheckToken(string token)        {            var principal = GetPrincipal(token);            if (principal is null)            {                return false;            }            return true;        }        ///         /// 擷取Token中的載荷資料        ///         /// token        ///         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 = (securityToken.Payload[JwtRegisteredClaimNames.Exp] ?? 0).TimeStampToDate()            };        }        ///         /// 擷取Token中的載荷資料        ///         /// 泛型        /// token        ///         public static T GetPayload(string token)        {            var jwtHandler = new JwtSecurityTokenHandler();            JwtSecurityToken jwtToken = jwtHandler.ReadJwtToken(token);            return JsonConvert.DeserializeObject(jwtToken.Payload.SerializeToJson());        }        ///         /// 判斷token是否過期        ///         ///         ///         public static bool IsExp(string token)        {            return GetPrincipal(token)?.Claims.First(c => c.Type == JwtRegisteredClaimNames.Exp)?.Value?.TimeStampToDate() < DateTime.Now;            //return GetPayload(token).ExpTime < DateTime.Now;        }        #region 從上下文請求流操作        ///         /// 判斷是否為AJAX請求        ///         ///         ///         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;        }        ///         /// 擷取Token        ///         /// 請求流        ///         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    }}
           

繼續閱讀