【问题标题】:Vue resource interceptor to refresh JWT tokenVue 资源拦截器刷新 JWT 令牌
【发布时间】:2021-05-17 11:46:07
【问题描述】:

我正在尝试编写一个 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();
            });
        }
    });
})

【问题讨论】:

    标签: vue.js vue-resource


    【解决方案1】:

    我认为回调的链接不太正确。对 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
      });
    })
    

    【讨论】:

    • 应用您建议的更改时,我收到TypeError: next(...).then is not a function. 不确定到底是什么问题?我的猜测是当response.status 没有Promise 附加then 到?即使这可行,我仍然怀疑第二次简单地调用next() 是行不通的。我不确定在第二次 next() 调用中是否以及如何修改 response 对象。
    • 我的错。如果状态为 200,第一次调用应该会解决承诺。我已经编辑了我的答案。最后一点,为什么要在第二次调用 next() 时修改响应?
    • 我认为return Promise.resolve(...)return Vue.http.post 的值都不会传播到next() 堆栈。这意味着我的拦截器调用next() 并在HTTP 调用完成后传递一个要在response 对象上执行的函数。但是,这个函数的结果似乎被忽略了。
    猜你喜欢
    • 2017-12-31
    • 2017-12-26
    • 2018-06-12
    • 2019-03-28
    • 2022-11-03
    • 2020-05-12
    • 2019-07-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多