zoukankan      html  css  js  c++  java
  • 弯道超车-Token处理

    弯道超车-Token处理

    一、 RefreshToken滑动过期处理:是在使用JWT进行授权的时候AccessToken过期了,然后通过如上token去重新获取可用的token,简单点就是说当用户在持续使用token的时候,我们需要做到每次在基础上加对应的时间,而不是直接跳转到登录首页。接下来就是介绍如何进行滑动过期的操作。先看如下图:

    1. 

    二、后端代码处理:

    1. 生成Token+RefreshToken,重点是第一步的时候,生成refreshToken的时候,需要把用户的信息缓存起来,方便下次使用该token来兑换。

    /// <summary>
            /// 生成Token+RefreshToken
            /// </summary>
            /// <param name="name"></param>
            /// <param name="password"></param>
            /// <returns></returns>
            [Route("LoginWithRefresh")]
            [HttpPost]
            public string LoginWithRefresh([FromForm] string name, [FromForm] string password)
            {
                Console.WriteLine($"This is LoginWithRefresh name={name} password={password}");
                if ("Eleven".Equals(name, StringComparison.OrdinalIgnoreCase) && "123456".Equals(password))//应该数据库
                {
                    CurrentUserModel currentUser = new CurrentUserModel()
                    {
                        Id = 123,
                        Account = "132313",
                        EMail = "test@qq.com",
                        Mobile = "123456",
                        Sex = 1,
                        Age = 33,
                        Name = "wj",
                        Role = "Admin"
                    };
    
                    var tokenPair = this._iJWTService.GetTokenWithRefresh(currentUser);
                    if (tokenPair != null && !string.IsNullOrEmpty(tokenPair.Item1))
                    {
                        return JsonConvert.SerializeObject(new AjaxResult<string>()
                        {
                            Result = true,
                            Message = "验证成功",
                            TValue = tokenPair.Item1,
                            OtherValue = tokenPair.Item2//写在OtherValue
                        });
                    }
                    else
                    {
                        return JsonConvert.SerializeObject(new AjaxResult<string>()
                        {
                            Result = false,
                            Message = "颁发token失败",
                            TValue = ""
                        });
                    }
                }
                else
                {
                    return JsonConvert.SerializeObject(new AjaxResult<string>()
                    {
                        Result = false,
                        Message = "验证失败",
                        TValue = ""
                    });
                }
            }

    2. 同时提供一个刷新token的方法: 通过refreshToken去换有效的token

     [Route("RefreshToken")]
            [HttpPost]
            public async Task<string> RefreshToken([FromForm] string refreshToken)
            {
                await Task.CompletedTask;
                if (!refreshToken.ValidateRefreshToken())
                {
                    return JsonConvert.SerializeObject(new AjaxResult<string>()
                    {
                        Result = false,
                        Message = "refreshToken过期了",
                        TValue = ""
                    });
                }
                var token = this._iJWTService.GetTokenByRefresh(refreshToken);
                if (!string.IsNullOrEmpty(token))
                {
                    return JsonConvert.SerializeObject(new AjaxResult<string>()
                    {
                        Result = true,
                        Message = "刷新Token成功",
                        TValue = token,
                        OtherValue = refreshToken//写在OtherValue
                    });
                }
                else
                {
                    return JsonConvert.SerializeObject(new AjaxResult<string>()
                    {
                        Result = false,
                        Message = "刷新token失败",
                        TValue = ""
                    });
                }
            }

    三、前端处理

    1. 前端主要是在调用的时候使用token去获取,然后发现token过期了,就调用获取refreshToken的方法,成功以后就继续执行之前的操作,反之就跳转登录页。

    相关代码示例:

    @section Scripts{
    <script type="text/javascript">
           $(function () {
                      $("#btnLogin").on("click", function () {
                          $.ajax({
                              url: "/Token/Login?Name=Eleven&Password=123456",
                              type: "get",
                              data: {},
                              success: function (data) {
                                  if(data.result){
                                     localStorage["token"] =data.tValue;
                                     alert(data.tValue);
                                   }
                               },
                               datatype: "json"
                           });
                      });
    
                        $("#btnGet").on("click", function () {
                          $.ajax({
                              url: "/Token/InfoGet",
                              type: "get",
                              data: {},
                              beforeSend: function (XHR) {
                                  //发送ajax请求之前向http的head里面加入验证信息
                                  XHR.setRequestHeader('Authorization', 'Bearer ' +  localStorage["token"]);
                              },
                              success: function (data) {
                                  alert(data.result);
                                   alert(data.tValue);
                                      }
                              , datatype: "json"
                            })
                          });
    
                       $("#btnPost").on("click", function () {
                          $.ajax({
                              url: "/Token/InfoPost",
                              type: "post",
                              data: {},
                              beforeSend: function (XHR) {
                                  //发送ajax请求之前向http的head里面加入验证信息
                                  XHR.setRequestHeader('Authorization', 'Bearer ' +  localStorage["token"]);
                              },
                              success: function (data) {
                                  alert(data.result);
                                   alert(data.tValue);
                                      }
                              , datatype: "json"
                            });
                          });
    
    
                          //Refresh
                          $("#btnLoginRefresh").on("click", function () {
                          $.ajax({
                              url: "/Token/LoginWithRefresh?Name=Eleven&Password=123456",
                              type: "get",
                              data: {},
                              success: function (data) {
                                  if(data.result){
                                     localStorage["accessToken"] =data.tValue;
                                     //alert(data.tValue);
                                     localStorage["refreshToken"] = data.otherValue;
                                     //alert(data.otherValue);
                                   }
                               },
                               datatype: "json"
                           });
                       });
    
                        $("#btnGetRefresh").on("click", function () {
                          $.ajax({
                              url: "/Token/InfoGet", type: "get", data: {},
                              beforeSend: function (XHR) {
                                  //发送ajax请求之前向http的head里面加入验证信息
                                  XHR.setRequestHeader('Authorization', 'Bearer ' +  localStorage["accessToken"]);
                              },
                              success: function (data) {
                                  alert(data.result+data.tValue);
                                      },
                              datatype: "json",
                              error:function(xhr, status, error){
                                     alert(xhr.getAllResponseHeaders());//打印全部头信息
                                     alert(xhr.status);//也可以用状态作比较
                                     if(xhr.getAllResponseHeaders().indexOf('jwtchallenge: expired')>0)
                                     {
                                         //refreshToken($("#btnGetRefresh").click);//直接传递回调最好,没成功
                                         refreshToken($("#btnGetRefresh"));//传递按钮
                                     }
                                  }
                                });
                          });
    
                          var refreshTime=0;
                          function refreshToken(callback){
                              alert("refresh-token");
                              if(refreshTime==0)
                              {
                                  refreshTime++;
                              }
                              else
                              {
                                  alert("需要重新登陆");
                                  //跳转登录页
                              }
                          $.ajax({
                              url: "/Token/LoginByRefresh",
                              type: "post",
                              data: {"refreshToken":localStorage["refreshToken"]},
                              success: function (data) {
                                  if(data.result){
                                     localStorage["accessToken"] =data.tValue;
                                     localStorage["refreshToken"] =data.otherValue;
                                     //alert(data.tValue);
                                     //callback();
                                     callback.trigger("click");
                                   }
                               },
                               datatype: "json"
                           });
                       }
    
                       $("#btnPostRefresh").on("click", function () {
                          $.ajax({
                              url: "/Token/InfoPost", type: "post", data: {},
                              beforeSend: function (XHR) {
                                  //发送ajax请求之前向http的head里面加入验证信息
                                  XHR.setRequestHeader('Authorization', 'Bearer ' +  localStorage["accessToken"]);
                              },
                              success: function (data) {
                                  alert(data.result);
                                   alert(data.tValue);
                                      }
                              , datatype: "json",
                               error:function(xhr, status, error){
                                  //alert(xhr.getAllResponseHeaders());//打印全部头信息
                                  //alert(xhr.status);//也可以用状态作比较
                                  if( xhr.getAllResponseHeaders().indexOf('jwtchallenge: expired')>0)
                                  {
                                      //refreshToken($("#btnGetRefresh").click);//直接传递回调最好,没成功
                                      refreshToken($("#btnGetRefresh"));//传递按钮
                                  }
                                  }
                             })
                          });
        });
    </script>
    }

    2. 解答:如何实现调用之前的接口的?

    关键代码:

    callback.trigger("click");

    四、在vue项目中如何进行执行之前接口的操作?

    参考代码如下:

    axios.interceptors.response.use(success, async (error) => {
     let {status} = error.response;
      if (status == 401) {
          let res = await getrefreshToken(refreshToken);
          window.localstorage.token = res.token;
          return axios.request(error.config);
      }
      return Promise.reject()
    })

    参考文章:https://www.jianshu.com/p/f2ca652a5d29

    以上就是token相关的整理,谢谢学习,点赞,关注,共同进步!!!

     

  • 相关阅读:
    HDU5000 (DP + 规律)
    HDU5127 神坑题---vector 、 list 、 deque 的用法区别
    HDU5128 细心、细心、细心
    dij单源最短路纯模板
    POJ 1236 SCC+缩点
    SCC(强连通分量)
    用树状数组求数组内的逆序对数
    HDU 1811 并查集
    大数模板,只要不是手敲,非常好用
    市赛
  • 原文地址:https://www.cnblogs.com/wangjinya/p/15358383.html
Copyright © 2011-2022 走看看