【发布时间】:2022-02-04 04:35:58
【问题描述】:
我已经使用访问令牌(jwt)和刷新令牌对单页应用程序和身份验证做出反应。我正在使用 axios 拦截器来处理它。
catch 中的代码未处理:
axios.interceptors.response.use(
(response) => response,
async (error) => {
const config = error.config
const headers = error.response?.headers
const TokenExpiredHeader =
headers && headers['token-expired'] === 'true'
if (
error?.response?.status === 401 &&
TokenExpiredHeader &&
!config._retry
) {
config._retry = true
return axios
.post('/Tokens/Refresh', {
accessToken: localStorage.getItem('accessToken')
})
.then((res) => {
localStorage.setItem(
'accessToken',
res.data.accessToken
)
return axios(config)
})
.catch((refreshErr) => {
// This code is not executed when receive error!
localStorage.removeItem('accessToken')
history.push(Paths.login())
return Promise.reject(error)
})
} else {
localStorage.removeItem('accessToken')
history.push(Paths.login())
}
return Promise.reject(error)
}
【问题讨论】:
-
看起来您可能会遇到拦截循环,因为两者都使用看似相同的 axios 实例。顺便说一句,因为您已经在使用
async,您可以使用const response = await axios.post(...)来提高可读性,而不是使用旧样式 then..catch。我还建议在您的 API 调用之前解析访问令牌,然后将其存储在本地存储中,以避免您遇到的问题。 -
我知道我用 try-catch 做到了,但无法处理 catch,所以我去了 then-catch。 NVM 但如果我将
return axios更改为axios它会进入 catch 但不会在我的组件中返回响应... -
另外我不想更改与身份验证相关的任何内容,因为我处理了很多情况,例如登录两台设备,然后从一台设备中删除帐户等,我认为这是最后一步跨度>
-
在失败后而不是在调用之前尝试刷新令牌似乎很奇怪。通常,如果您遇到这样的身份验证失败,则通常认为登录会话已过期。你在这里的意图是什么?
-
没什么具体的。我刚开始这样做是因为我遵循了互联网上的最佳实践。是的,在你的为什么我会少 1 个 req-res,这听起来更好一些。我会试试看。你会建议我什么?在请求拦截器 -> jwt_decode -> 如果过期 -> 刷新?问题是我处理了所有场景,但我坚持这样做。
标签: reactjs typescript axios jwt refresh-token