新建.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(new23 {24 token = new JwtSecurityTokenHandler().WriteToken(token)25 });26 }27 else28 {29 return BadRequest(new { message = "username or password is incorrect." });30 }31 }
在login接口中的Const.Domain需要新建一个类Const.cs,用来保存密钥
1 public class Const2 {3 /// 4 /// 这里为了演示,写死一个密钥。实际生产环境可以从配置文件读取,这个是用网上工具随便生成的一个密钥5 /// 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,//是否验证Issuer10 ValidateAudience = true,//是否验证Audience11 ValidateLifetime = true,//是否验证失效时间12 ClockSkew = TimeSpan.FromSeconds(30),13 ValidateIssuerSigningKey = true,//是否验证SecurityKey14 ValidAudience = Const.Domain,//Audience15 ValidIssuer = Const.Domain,//Issuer,这两项和前面签发jwt的设置一致16 IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Const.SecurityKey))//拿到SecurityKey17 };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状态码,无权限访问