JWT用来验证访问者身份,需要以下内容:
1、一个密钥,32位,越复杂越好,我用两个GUID去掉-后拼在一起。
2、一个json格式的配置文件,里面保存密钥和过期时间。
"JWTSetting": { "SecKey": "41492fbc0bd046fe8c8562657897b268b9201e4afbbf46e0b08f09051ff286144", "Expires": 1 },
3、一个payload段的对象模型,用来生成JWT的payload段数据,还可以用来还原对象。
/// <summary> /// 配合JWTHelper中的Claim,属性全部用小写,与系统自带的统一。 /// </summary> public class JwtPayloadModel { public string nameidentifier { get; set; } =string.Empty; public string name { get; set; } = string.Empty; public List<string> roles { get; set; } = new List<string>(); public string passport { get; set; } = string.Empty; public string exp { get; set; }=string.Empty; /// <summary> /// 版本号,为了实现token过期的自增数,可以放到数据库或redis中,每次登录后自增。 /// 调用接口时对比版本号大小,判断是否过期,过期则提示token过期需要重新登录。 /// (实际上用户token并未过期,只是为了实现多点登录唯一做出的变通) /// </summary> public long version { get; set; } }
4、一个生成JWT的函数,需要用到密钥、payload段数据和过期时间。
/// <summary> /// 加密 /// </summary> /// <param name="key">密钥</param> /// <param name="expiresHour">到期时间(小时)</param> /// <param name="payload">payload</param> /// <returns></returns> public static string Encryption(string key, JwtPayloadModel payload, int expiresHour = 24) { var claims = new List<Claim>(); claims.Add(new Claim(ClaimTypes.NameIdentifier, payload.nameidentifier)); claims.Add(new Claim(ClaimTypes.Name, payload.name)); for (int i = 0; i < payload.roles.Count; i++) { claims.Add(new Claim(ClaimTypes.Role, payload.roles[i])); } claims.Add(new Claim("passport", payload.passport)); claims.Add(new Claim("version", payload.version.ToString())); /* claims.Add(new Claim(ClaimTypes.NameIdentifier, "1")); claims.Add(new Claim(ClaimTypes.Name, "root")); claims.Add(new Claim(ClaimTypes.Role, "Admin"));*/ DateTime expires = DateTime.Now.AddHours(expiresHour); byte[] secBytes = Encoding.UTF8.GetBytes(key); var secKey = new SymmetricSecurityKey(secBytes); var credentials = new SigningCredentials(secKey, SecurityAlgorithms.HmacSha256Signature); var tokenDescriptor = new JwtSecurityToken(claims: claims, expires: expires, signingCredentials: credentials); string jwt = new JwtSecurityTokenHandler().WriteToken(tokenDescriptor); return jwt; }
5、Program中增加JWT验证代码。
//配置jwt验证 void ConfigureJWT() { builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(x => { var jwtOpt = builder.Configuration.GetSection("JWTSetting").Get<TDAuth.JWTSetting>(); byte[] keyBytes = Encoding.UTF8.GetBytes(jwtOpt?.SecKey ?? ""); var secKey = new SymmetricSecurityKey(keyBytes); x.TokenValidationParameters = new() { ValidateIssuer = false, ValidateAudience = false, ValidateLifetime = true, ValidateIssuerSigningKey = true, IssuerSigningKey = secKey }; //增加对SignalR调用者的身份验证 x.Events = new JwtBearerEvents { OnMessageReceived = context => { var accessToken = context.Request.Query["access_token"]; var path = context.HttpContext.Request.Path; if(!string.IsNullOrEmpty(accessToken) &&path.StartsWithSegments("/Hubs/Demo")) { context.Token = accessToken; } return Task.CompletedTask; } }; }); }
6、在需要验证的代码段前加[Authorize]标记。
/// <summary> /// jwt还原 /// </summary> /// <returns></returns> [HttpPost] [Route("/ReductionJWT")] [Authorize] public ActionResult ReJWT(string jwt) { string key = _jwtSetting.Value.SecKey ?? "12345678901234567890"; TDAuth.JwtPayloadModel model = TDAuth.JWTHelper.Decode(key, jwt); return Ok(model); }
7、配置Swagger支持输入JWT
//配置swagger void ConfigureSwagger() { builder.Services.AddSwaggerGen(options => { options.SwaggerDoc("v1", new OpenApiInfo { Version = "v1", Title = "API标题", Description = "API描述" }); var xmlFilename = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, xmlFilename)); }); builder.Services.AddSwaggerGen(c => { var scheme = new OpenApiSecurityScheme() { Description = "Authorization header. \r\nExample: 'Bearer 12345abcdef'", Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Authorization" }, Scheme = "oauth2", Name = "Authorization", In = ParameterLocation.Header, Type = SecuritySchemeType.ApiKey, }; c.AddSecurityDefinition("Authorization", scheme); var requirement = new OpenApiSecurityRequirement(); requirement[scheme] = new List<string>(); c.AddSecurityRequirement(requirement); }); }
标签:claims,string,JWT,public,使用,var,new,payload From: https://www.cnblogs.com/tudou365/p/17064289.html