Vue 资源拦截器刷新 JWT 令牌
Posted
技术标签:
【中文标题】Vue 资源拦截器刷新 JWT 令牌【英文标题】:Vue resource interceptor to refresh JWT token 【发布时间】: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();
);
);
)
【问题讨论】:
【参考方案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
对象上执行的函数。但是,这个函数的结果似乎被忽略了。以上是关于Vue 资源拦截器刷新 JWT 令牌的主要内容,如果未能解决你的问题,请参考以下文章
Angular 4.3 - HTTP 拦截器 - 刷新 JWT 令牌