为了验证使用者的身份,需要客户端向服务器端提供一个可靠的验证信息,称为Token,这个token通常由Json数据格式组成,通过hash散列算法生成一个字符串,所以称为Json Web Token(Json表示令牌的原始值是一个Json格式的数据,web表示是在互联网传播的,token表示令牌,简称JWT)。
新建 .Core WebApi项目,并引入包
install-package Microsoft.AspNetCore.Authentication.JwtBearer -Version 3.0.3
install-package System.IdentityModel.Tokens.Jwt –Version 6.16.0
public class JwtTokenUtil
{
private readonly IConfiguration _configuration;
public JwtTokenUtil(IConfiguration configuration)
{
_configuration = configuration;
}
public string GetToken(User user)
{
// push the user’s name into a claim, so we can identify the user later on.
var claims = new[]
{
new Claim(ClaimTypes.Name, user.name),
//new Claim(ClaimTypes.Role, admin)//在这可以分配用户角色,比如管理员 、 vip会员 、 普通用户等
};
//sign the token using a secret key.This secret will be shared between your API and anything that needs to check that the token is legit.
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["SecurityKey"])); // 获取密钥
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); //凭证 ,根据密钥生成
//.NET Core’s JwtSecurityToken class takes on the heavy lifting and actually creates the token.
/**
* Claims (Payload)
Claims 部分包含了一些跟这个 token 有关的重要信息。 JWT 标准规定了一些字段,下面节选一些字段:
iss: The issuer of the token,token 是给谁的 发送者
aud: 接收的
sub: The subject of the token,token 主题
exp: Expiration Time。 token 过期时间,Unix 时间戳格式
iat: Issued At。 token 创建时间, Unix 时间戳格式
jti: JWT ID。针对当前 token 的唯一标识
除了规定的字段外,可以包含其他任何 JSON 兼容的字段。
* */
var token = new JwtSecurityToken(
issuer: "jwttest",
audience: "jwttest",
claims: claims,
expires: DateTime.Now.AddMinutes(60*9),
signingCredentials: creds
);
return new JwtSecurityTokenHandler().WriteToken(token);
}
}
namespace JwtToken.Controllers
{
[ApiController]
[Route("api/[controller]")]
public class HomeController : Controller
{
List users = new List() {
new User{ name = "admin",password = "admin"},
new User{ name = "xiaoxiao",password = "xiaoxiao"}
};
private readonly IConfiguration _configuration;
public HomeController(IConfiguration configuration)
{
_configuration = configuration;
}
//登录操作
[HttpPost]
public JsonResult login([FromForm] User model)
{
UserMsg msg = new UserMsg()
{
mark = 0,
msg = "",
token = "",
};
//User user = _context.User.Where(x => x.name == model.name).FirstOrDefault();
User user = users.Where(x => x.name == model.name).FirstOrDefault();
//string password_form = _common.Get_MD5_Method1(model.password);
string password_form = model.password;
if (user != null && user.password == password_form.ToLower())
{
JwtTokenUtil jwtTokenUtil = new JwtTokenUtil(_configuration);
string token = jwtTokenUtil.GetToken(user); //生成token
//var headers = new HttpResponseMessage().Headers;
//headers.Add("Authorization",token);
msg.mark = 1;
msg.msg = "登录成功";
msg.token = token;
}
else
{
msg.msg = "用户名或者密码错误";
}
return Json(msg);
}
}
}
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
//添加jwt验证:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options => {
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,//是否验证Issuer
ValidateAudience = true,//是否验证Audience
ValidateLifetime = true,//是否验证失效时间
ValidateIssuerSigningKey = true,//是否验证SecurityKey
ValidAudience = "jwttest",//Audience
ValidIssuer = "jwttest",//Issuer,这两项和前面签发jwt的设置一致
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["SecurityKey"]))//拿到SecurityKey
};
});
services.AddControllers();
}
app.UseAuthentication();//启用验证
在需要token验证的类或方法上添加特性[Authorize]
[Route("api/[controller]")]
public class TestController : Controller
{
// GET api/values
[HttpGet]
[Authorize]//添加Authorize标签,可以加在方法上,也可以加在类上
public ActionResult> Get()
{
return new string[] { "value1", "value2" };
}
// GET api/values/5
[HttpGet("{id}")]
public string Get(int id)
{
return "value";
}
}
6. 其他
对应资源:
(4条消息) ASP.NETCore3.1JWTtoken实现与应用-C#文档类资源-CSDN文库
参考博客:
ASP.NET Core 2.1 JWT token (一) - 简书 (jianshu.com)
JWT-生成、校验、解析Token(C#) - .Neterr - 博客园 (cnblogs.com)