前端实现token无感刷新

需求

当token过期的时候,刷新token,前端需要做到无感刷新token,即刷token时要做到用户无感知,避免频繁登录。实现思路

方法一

后端返回过期时间,前端判断token过期时间,去调用刷新token接口

缺点:需要后端额外提供一个token过期时间的字段;使用了本地时间判断,若本地时间被篡改,特别是本地时间比服务器时间慢时,拦截会失败。

方法二(可行)

写个定时器,定时刷新token接口

缺点:浪费资源,消耗性能,不建议采用。

方法三 (推荐)

在响应拦截器中拦截,判断token 返回过期后,调用刷新token接口

思考:

我在遇到同样问题的时候也是考虑了两种方法,一种是定时刷新一种是过期时刷新。 但是我选择了定时刷新的方案。 假如token 的过期时间是5分钟,那么在高频率使用的情况下(每秒访问接口)每隔5分钟就会刷新一次token。如果web端有大屏展示页面的话,过期刷新的方案跟定时刷新的方案调用的token次数其实一样。但过期刷新的时候可能会阻碍接口的请求,导致每隔5分钟会出现一次接口变慢的情况。 测试下发现,用定时刷新的方案并不会浪费资源,唯一的代价就是需要运行一个定时器。

后端每个需要token的接口,都返回token的失效时间指的是定时器的时间也是后端返回token失效的时间

实现:axios的基本骨架,利用service.interceptors.response进行拦截

importaxiosfrom'

axios'service.interceptors.response.use(response=>    
    {
        if(response.data.code ===409) {
            returnrefreshToken({
                refreshToken:localStorage.getItem('refreshToken'),token: getToken() })
                    .then(res=>  {
                        const{ token } = res.data 
                        setToken(token) 
                        response.headers.Authorization =`${token}`}).catch(err=>    {          
                            removeToken()          
                            router.push('/login')
                            returnPromise.reject(err)        
                        })    }
                   return response && response.data  },(error) =>{    
                        Message.error(error.response.data.msg)
                        returnPromise.reject(error) 
                    })

你可能感兴趣的:(前端,javascript,java)