/// <summary> /// Jwt 注册服务 /// </summary> /// <param name="services"></param> public static void AddJwt(this IServiceCollection services) { if (services == null) { throw new ArgumentNullException(nameof(services)); } byte[] KeyByteArray = Encoding.ASCII.GetBytes(JwtAppSetting.SecretKey()); SymmetricSecurityKey signingKey = new SymmetricSecurityKey(KeyByteArray); //令牌验证参数 var tokenValidationParameters = new TokenValidationParameters { ValidateIssuerSigningKey = true, IssuerSigningKey = signingKey, ValidateIssuer = true, ValidIssuer = JwtAppSetting.Issuer(), //发行人 ValidateAudience = true, ValidAudience = JwtAppSetting.Audience(), //订阅人 ValidateLifetime = true, ClockSkew = TimeSpan.FromSeconds(30), //token过期后 还可以继续多访问30秒 RequireExpirationTime = true, }; //2.1 [认证] core 自带官方认证 services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) // 添加JwtBearer服务 .AddJwtBearer(o => { o.TokenValidationParameters = tokenValidationParameters; o.Events = new JwtBearerEvents { OnAuthenticationFailed = context => { // 如果过期,则把<是否过期>添加到,返回头信息中 if (context.Exception.GetType() == typeof(SecurityTokenExpiredException)) { context.Response.Headers.Add("Token-Expired", "true"); } return(Task.CompletedTask); } }; }); }
/// <summary> /// 获取Token /// </summary> /// <param name="token">Token令牌</param> /// <returns></returns> public static string IssueJwt(Token token) { List <Claim> claims = new List <Claim> { /* * 特别重要: * 1、这里将用户的部分信息,比如 uid 存到了Claim 中,如果你想知道如何在其他地方将这个 uid从 Token 中取出来, * 请看下边的SerializeJwt() 方法,或者在整个解决方案,搜索这个方法,看哪里使用了! * 2、你也可以研究下 HttpContext.User.Claims ,具体的你可以看看 Policys/PermissionHandler.cs 类中是如何使用的。 */ //Jti 编号 Iat 签发时间 Nbf 生效时间 Exp 过期时间 new Claim(JwtRegisteredClaimNames.Jti, token.Uid), new Claim(JwtRegisteredClaimNames.Iss, JwtAppSetting.Issuer()), new Claim(JwtRegisteredClaimNames.Aud, JwtAppSetting.Audience()), new Claim(JwtRegisteredClaimNames.Iat, $"{new DateTimeOffset( DateTime.Now).ToUnixTimeSeconds()}"), new Claim(JwtRegisteredClaimNames.Nbf, $"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}"), //这个就是过期时间,目前是过期1000秒,可自定义,注意JWT有自己的缓冲过期时间 new Claim(JwtRegisteredClaimNames.Exp, $"{new DateTimeOffset(DateTime.Now.AddSeconds(1000)).ToUnixTimeSeconds()}"), new Claim(ClaimTypes.Expiration, DateTime.Now.AddSeconds(1000).ToString()), }; // 可以将一个用户的多个角色全部赋予; claims.AddRange(token.Role.Split(',').Select(s => new Claim(ClaimTypes.Role, s))); //秘钥 (SymmetricSecurityKey 对安全性的要求,密钥的长度太短会报出异常) SymmetricSecurityKey key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(JwtAppSetting.SecretKey())); SigningCredentials creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); JwtSecurityToken jwt = new JwtSecurityToken( issuer: JwtAppSetting.Issuer(), claims: claims, signingCredentials: creds); JwtSecurityTokenHandler jwtHandler = new JwtSecurityTokenHandler(); string encodedJwt = jwtHandler.WriteToken(jwt); return(encodedJwt); }