前言
在网上走一朝JWT,都会拿来和Session对比,这里不细说理论了,大家伙们百度找找,很多,很详细;这里我们直接实操JWT在Asp.NetCore3.1中的应用;
走起
1. 建一个WebAPI项目(之前都截图好多了,这里不截图了);
2. Nuget包中安装对应组件

3. 在Startup.cs文件中进行配置
ConfigureServices方法
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
//获取配置文件信息,因为是共用的,所以就统一放配置文件了
string secret = Configuration.GetValue<string>("JWT:Secrete");//秘钥,这里的秘钥长度不低于16
string issuer_z = Configuration.GetValue<string>("JWT:Issuer");//颁发方
string audience_z = Configuration.GetValue<string>("JWT:Audience");//接收方
//开始配置JWT
services.AddAuthentication("Bearer")
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
//是否验证秘钥
ValidateIssuerSigningKey = true,
//秘钥,记住一定要大于等于16位
IssuerSigningKey=new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secret)),
//是否验证颁发者
ValidateIssuer=true,
//颁发者
ValidIssuer= issuer_z,
//是否验证接收方
ValidateAudience=true,
ValidAudience= audience_z,
//必须要有超时时间
RequireExpirationTime=true,
//是否验证超时,当设置exp和nbf时有效,同时启用ClockSkew
ValidateLifetime=true,
//这是一个缓冲时间,系统默认是5分钟,可设置;则Token有效时间就是过期时间+这个设置的缓冲时间
ClockSkew=TimeSpan.FromSeconds(50)
};
});
}
Configure方法
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
4. 在对应Controller上或Action上加上Authorize标记

经过以上四步,基本上就用JWT对API进行认证保护,不信试一下,程序运行起来,Postman走起:
其他接口没加Authorize特性的,正常访问,如下:

加了特性的Action,访问返回401,如下:

也就是说,加了Authorize特性的Action需要进行认证才能进行访问;换句话来说,请求来的信息,需要服务端能解析验证,JWT通过Token实现的;
生成Token
在UserController下增加一个获取Token的方法,如下:
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
namespace JwtDemo.Controllers
{
[Route("[controller]/[action]")]
[ApiController]
public class UserController : ControllerBase
{
private readonly IConfiguration _configuration;
public UserController(IConfiguration configuration)
{
_configuration = configuration;
}
[Authorize]
public IActionResult UserInfo()
{
return Ok(new { Name = "Zoe", Age = 18 });
}
[HttpPost]
public IActionResult GetToken(User u)
{
if(u==null||string.IsNullOrEmpty(u.LoginName)||string.IsNullOrEmpty(u.LoginPwd))
{
return Ok(new { code=-1,msg="用户名或密码不能为空"});
}
//验证用户
if(u.LoginName!="Zoe"&&u.LoginPwd!="admin")
{
return Ok(new { code = -1, msg = "用户名或密码错误" });
}
//验证成功,构建Token
string strToken = GenerateToken(u);
//返回信息
return Ok(new {code=1,msg="Success",data=new { LoginName=u.LoginName,Token=strToken,Expire=3600,TokenType=JwtBearerDefaults.AuthenticationScheme } });
}
private string GenerateToken(User u)
{
//这里也是从配置文件读取的,和上面读取的一致,否则开启对应验证的话会不通过
string secret = _configuration.GetValue<string>("JWT:Secrete");
string issuer_z = _configuration.GetValue<string>("JWT:Issuer");
string audience_z = _configuration.GetValue<string>("JWT:Audience");
//指定加密算法
var securityKey = new SigningCredentials(new SymmetricSecurityKey(Encoding.ASCII.GetBytes(secret)), SecurityAlgorithms.HmacSha256);
//可以在Token里增加信息,但这里不要加私密信息,比如密码等这种数据
var claims = new Claim[] { new Claim("UserName", u.LoginName) };
//组装数据
SecurityToken securityToken = new JwtSecurityToken(
issuer: issuer_z,//颁发者
audience: audience_z,//接收者
signingCredentials: securityKey,//组装的秘钥
expires:DateTime.Now.AddHours(1),//有效时间
claims: claims
);
//生成Token
return new JwtSecurityTokenHandler().WriteToken(securityToken);
}
}
public class User
{
public string LoginName{ get; set; }
public string LoginPwd{ get; set; }
}
}
这样Token就搞定了,项目运行起来,Postman访问一下:

这样我们就可以拿着这个Token进行保护API访问了,前提是在有效期之内,生成的Token可以在JWT.io官网进行解析,如下:

Token在Postman中使用,把生成的Token靠到Token的位置,访问保护的API,如下可以访问了:

其实本质就是在请求头Authorization中加上"Bearer 生成的Token",中间一定要有空格;前度调用的话也是在请求头中添加就行;

总结
JWT使用是不是很简单,轻松实现API的认证保护;下一遍我们说说JWT的权限验证;
关注公众号,每周更新至少两篇关于.NetCore相关文章

