Vue资源拦截器刷新JWT令牌

时间:2021-02-14 08:28:41

标签: vue.js vue-resource

我正在尝试编写一个 vue-resource 拦截器,它会在 JWT 访问令牌过期时刷新它。我假设我需要一个请求后回调来检查令牌过期错误(在我的例子中为 status == 401),然后调用刷新端点并重试初始请求。

使用下面的代码,我面临的唯一问题是刷新令牌后的 next() 调用永远不会发生,即使刷新执行正常并且新令牌保存到 localStorage

Vue.http.interceptors.push(function (request, next) {

    if (!request.headers.has('Authorization') && window.localStorage.access_token) {
        request.headers.set('Authorization', `Bearer ${window.localStorage.access_token}`);
    }

    next(function (response) {
        if (response.status === 401) {
            const refreshToken = localStorage.getItem('refresh_token');

            Vue.http.post('/api/v4/auth/refresh', null, {
                headers: {'Authorization': `Bearer ${refreshToken}`}
            }).then((response) => {
                localStorage.setItem('access_token', response.data.accessToken);
                localStorage.setItem('refresh_token', response.data.refreshToken);
            }).then(() => {
                next();
            });
        }
    });
})

1 个答案:

答案 0 :(得分:0)

我认为回调的链接不太正确。对 next 的第二次调用应该在第一次调用返回一个 promise 时发生,并且不应该依赖于应用于解决第一个 promise 的逻辑,而应该依赖于该 promise 的成功解析。

Vue.http.interceptors.push(function (request, next) {

  if (!request.headers.has('Authorization') && window.localStorage.access_token) {
    request.headers.set('Authorization', `Bearer ${window.localStorage.access_token}`);
  }

  next(function (response) {
    if (response.status === 401) {
        const refreshToken = localStorage.getItem('refresh_token');

        return Vue.http.post('/api/v4/auth/refresh', null, {
            headers: {'Authorization': `Bearer ${refreshToken}`}
        }).then((response) => {
            localStorage.setItem('access_token', response.data.accessToken);
            localStorage.setItem('refresh_token', response.data.refreshToken);
        })
    }
    return Promise.resolve(response)
  }).then(() => {
     next(); // This is called whenever the first callback returns a promise
  });
})