新建.net core web的api项目(.net core版本3.1)
在Value控制器下写一个模拟登录接口,进行简单的名字和密码验证即可。验证通过后会返回一个token。
1 [HttpGet] 2 [Route("api/login")] 3 public IActionResult Login(string userName,string pwd) 4 { 5 if (!string.IsNullOrEmpty(userName) && !string.IsNullOrEmpty(pwd)) 6 { 7 var claims = new[] 8 { 9 new Claim(JwtRegisteredClaimNames.Nbf,$"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}") , 10 new Claim (JwtRegisteredClaimNames.Exp,$"{new DateTimeOffset(DateTime.Now.AddMinutes(30)).ToUnixTimeSeconds()}"), 11 new Claim(ClaimTypes.Name, userName) 12 }; 13 var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Const.SecurityKey)); 14 var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); 15 var token = new JwtSecurityToken( 16 issuer: Const.Domain, 17 audience: Const.Domain, 18 claims: claims, 19 expires: DateTime.Now.AddMinutes(30), 20 signingCredentials: creds); 21 22 return Ok(new 23 { 24 token = new JwtSecurityTokenHandler().WriteToken(token) 25 }); 26 } 27 else 28 { 29 return BadRequest(new { message = "username or password is incorrect." }); 30 } 31 }
在login接口中的Const.Domain需要新建一个类Const.cs,用来保存密钥
1 public class Const 2 { 3 /// <summary> 4 /// 这里为了演示,写死一个密钥。实际生产环境可以从配置文件读取,这个是用网上工具随便生成的一个密钥 5 /// </summary> 6 public const string SecurityKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDI2a2EJ7m872v0afyoSDJT2o1+SitIeJSWtLJU8/Wz2m7gStexajkeD+Lka6DSTy8gt9UwfgVQo6uKjVLG5Ex7PiGOODVqAEghBuS7JzIYU5RvI543nNDAPfnJsas96mSA7L/mD7RTE2drj6hf3oZjJpMPZUQI/B1Qjb5H3K3PNwIDAQAB"; 7 public const string Domain = "http://localhost:5000"; 8 }
在Startup.cs文件中添加JWT服务
1 public void ConfigureServices(IServiceCollection services) 2 { 3 4 #region JWT验证 5 services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) 6 .AddJwtBearer(options => { 7 options.TokenValidationParameters = new TokenValidationParameters 8 { 9 ValidateIssuer = true,//是否验证Issuer 10 ValidateAudience = true,//是否验证Audience 11 ValidateLifetime = true,//是否验证失效时间 12 ClockSkew = TimeSpan.FromSeconds(30), 13 ValidateIssuerSigningKey = true,//是否验证SecurityKey 14 ValidAudience = Const.Domain,//Audience 15 ValidIssuer = Const.Domain,//Issuer,这两项和前面签发jwt的设置一致 16 IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Const.SecurityKey))//拿到SecurityKey 17 }; 18 }); 19 #endregion
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); 20 }
在其后的Configure函数中添加启动中间件
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseRouting(); //开启JWT验证中间件 //.net core3比.net core2多加一个UseAuthentication,而且必须在UseAuthorization前面 //这是认证 app.UseAuthentication(); //这是授权 app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); }
新建一个get接口用于测试JWT验证是否成功
1 [HttpGet] 2 [Route("api/get")] 3 //JWT验证标识 4 [Authorize] 5 public ActionResult<IEnumerable<string>> Get() 6 { 7 return new string[] { "value1", "value2" }; 8 }
打开PostMan测试登录接口
复制登录接口得到的token,在Headers请求头里添加参数Authorization值为Bearer+空格+token
当把Authorization去掉则会出现401状态码,无权限访问