token刷新

我把token放在cookie中,cookie设置略小于后台设置的过期时间,在每次请求前判断cookie是否过期,若过期则先获取新的token再继续请求

checkToken().then(
    function(data){
        axios.get(url, {
            params: params
        }).then(function(res) {
            callback(res);
        }).catch(function(error) {
            if(err) {
                callback('error');
            }
        })
    }
)
//判断是否需要重新获取token
function checkToken () {
    var p = new Promise(function(resolve, reject){
           let m_access_token = getCookie('m_access_token');
        let refresh_token = getCookie('m_refresh_token');
        if(m_access_token){
            resolve();
        }else{
            axios({
                method: 'post',
                url:paths.loginpath+ '/refreshToken',
                data: Qs.stringify({refresh_token:refresh_token})
            }).then(function(res) {
                addCookie('m_access_token', res.data.access_token,1);
                addCookie('m_refresh_token', res.data.refresh_token,2);
                resolve();
            }).catch(function(error) {
                reject();
            });
        }
    });
    return p;
};

这样的话有个问题,一个页面打开的请求会不只一个,若打开页面的时候token过期的话就会请求多次刷新token,感觉这样不合理,而且会导致先请求的接口所携带的token过期了

阅读 11.6k
5 个回答
window.tokenLock = fasle;
function checkLock (cb){
    if(window.tokenLock){
        setTimeout(function(){
            checkLock()
        },500)
    }else{
        window.tokenLock = fasle;
        cb(function(){
            axios.get(url, {
                params: params
            }).then(function(res) {
                callback(res);
            }).catch(function(error) {
                if(err) {
                    callback('error');
                }
            })
        })
    }
}
function checkToken (){
    if(window.tokenLock){
        checkLock()
    }
    window.tokenLock = true;
    
}

加个锁 大概参考一下

首先,如果每个请求都是独立的,其实是没有太好的方法去做到只刷新一次token

那么换个思路,axios是有过滤器这个概念的,首先我们在过滤器中获取到token,并且判断token是否过期,过期的话就去后端获取新的token。设置一个公共变量设置是否正在获取cookie,其他请求发现有其他请求正在获取token,则去定时获取token,直到获取到token才进行真正的请求。

其实思路大体和 @追逆风 差不多

还有一种解决方法,就是单独设置一个授权页面,当发现token过期需要刷新cookie,则直接跳转到授权页面,在这个页面里请求token,然后在回跳到原来的页面上。其实,你认真观察的话,微信授权或者其他第三方授权都是类似的逻辑,推荐这种做法。

var isGetting = false;  //是否正在获取token

function fetch(url) {
  //检测token过期
  if (!checkToken()) {
    //如果没有获取
    if (!isGetting) {  
      fetch('token');
    } 
    //如果正在获取
    else {
      return new Promise(function (resolve, reject) {
        //定时继续请求原url,如果token过期,还是会执行到这儿
        setTimeout(function () {
          return fetch(url);
        }, 500);
      });
    }
  }
  //正常发送http请求
  return axios.get(url);
}

fetch(url1);
fetch(url2);

你如果token 没有过期 就return啊 别去重复获取新的token 啊

function checkToken 你这个函数 判断如果不过期 就return 别执行从后台请求获取token 不就好了

clipboard.png

clipboard.png
他只会执行一次

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题