美文网首页
Asp.net WebAPI 使用JWT

Asp.net WebAPI 使用JWT

作者: 凌雲木 | 来源:发表于2018-08-24 18:05 被阅读1160次

本文主要介绍在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

相关文章

网友评论

      本文标题:Asp.net WebAPI 使用JWT

      本文链接:https://www.haomeiwen.com/subject/wxkiiftx.html