本文主要介绍在Asp.net API采用JWT对接口进行Token校验的教程
准备工作:
- 1 需要提前了解JWT生成Token的逻辑
- 2服务端需要安装JWT客户端与Redis缓存服务器,Token保存在Redis中
- 3 客户端采用的layui自定义封装的Ajax 模块请求接口
接口请求流程图
请求流程
-
步骤1:客户端向服务端请求数据之前,先向服务端请求token
客户端代码请求Token代码:
layui.use(['jquery', 'layer', 'axioshelper'], function () {
var $ = layui.$;
var axioshelper = layui.axioshelper;
$("#btn").click(function () {
var pre = {};
pre.Uaccount = "admin";
pre.Upwd="123456";
pre.Sub = "123456";
var request = {};
request.type = 'POST';
request.url = 'http://localhost:7192/api/SystemToken?expiresAbsoulute=1';
request.data = pre;
request.datatype = "json";
//request.token = $("#Token").val();
request.success = function (result) {
console.log(result);
}
axioshelper.ajax(request);
});
-
步骤2:服务端验证通过登陆名和密码后,生成JWT Token 返回给客户端
客户端把用户名和密码传递到服务端,如果用户名和密码正确,则返回一个Token ,此Token保存在Redis中,并带有过期时间
在此当用户名和密码为 "admin" && "123456"时,登录成功,通过 JwtHelper.GetToken生成 JWT Token
服务端生成Token接口:
/// <summary>
/// 生成Token
/// </summary>
/// <param name="model">s实体类</param>
/// <param name="expiresAbsoulute">绝对过期时间(单位小时)</param>
/// <returns></returns>
[HttpPost]
public IHttpActionResult GetToken([FromBody] TokenModel model, int expiresAbsoulute=24)
{
if (model.Uaccount == "admin" && model.Upwd == "123456")
{
//string jwtStr = TokenHelper.IssueJWT(model);
bool result = JwtHelper.GetToken(model,out string jwtStr);
if (result)
{
return Ok(jwtStr);
}
}
return BadRequest();
}
#endregion
public static bool GetToken(TokenModel tokenModel , out string result,int expiresSliding = 5, int expiresAbsoulute = 24)
{
result = "";
try
{
DateTime UTC = DateTime.Now;
var payload = new Dictionary<string, object>
{
{"sub",tokenModel.Sub},
//{"jti",Guid.NewGuid().ToString() },//JWT ID,JWT的唯一标识
{"iat", UTC.ToString() },//JWT颁发的时间
{"issuer","凌云木"},//签发者
{"audience", tokenModel.Uaccount},//jwt的接收该方,非必须
{"exp",UTC.AddHours(expiresAbsoulute).ToString()},//JWT生命周期
};
IJwtAlgorithm algorithm = new HMACSHA256Algorithm();
IJsonSerializer serializer = new JsonNetSerializer();
IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
IJwtEncoder encoder = new JwtEncoder(algorithm, serializer, urlEncoder);
result = encoder.Encode(payload, secret);
RedisHelper redis = new RedisHelper();
var a=redis.SetStringKey(EncryptionAlgorithm.EncryptString(result), result, TimeSpan.FromMinutes(5));
return a;
}
catch (Exception e)
{
LogHelper.WriteErrorLog("DecodeJwtToken", $"{e}");
return false;
}
Token
-
步骤3:客户端用带有Token的请求头向服务端请求数据
var request = {};
request.type = 'GET';
request.url = 'http://localhost:7192/api/Values?id=1';
request.datatype = "json";
request.token = token;
request.success = function (result) {
console.log(result);
//alert(result);
}
axioshelper.ajax(request);
服务端返回数据之前先要校验Token是否有效,
1 查看Redis是否存有此Token
2
private bool ValidateToken(string encryptToken)
{
var rediskey= EncryptionAlgorithm.EncryptString(encryptToken);
var rediskeyvalue= redis.GetStringValue(rediskey);//校验Redis中是否含有此Token
if (rediskeyvalue != encryptToken)
{
return false;
}
//解析Token
if (!JwtHelper.DecodeJwtToken(encryptToken, out string result))
{
return false;
}
if (!JsonHelper.DeserializeJsonToObject<TokenAnalysis>(result, out TokenAnalysis TokenModel))
{
return false;
}
//判断Token的绝对过期时间
if (TokenModel.exp > DateTime.Now)
{
redis.SetStringKey(rediskey, encryptToken, TimeSpan.FromMinutes(5));
return true;
}
return false;
}
-
步骤4:服务端返回请求数据
image.png
如果不带Token请求服务数据时
image.png