我有一个带有登录组件的react应用。登录时,我收到访问令牌和刷新令牌,并将它们保存在本地存储中以供使用。一小时(3600秒)后,访问令牌将过期,并且每当我调用API时,访问令牌都会返回错误状态代码401(“未经授权”)。为了解决这种情况并触发更新访问令牌的功能,我实现了Axios拦截器。我已设置以下代码来捕获401错误,并用新令牌替换localStorage并调用以前失败的API。
问题在于,即使在更新本地存储之后,先前的API调用也会使用旧令牌而不是新令牌,并再次返回401。因此,我必须将页面重新加载一次以获得API成功。如何解决此问题并立即获得API调用?
Axios组件:
import axios from 'axios';
import AUTH from '../auth';
var accessToken = localStorage.getItem('accessToken');
var refreshToken = localStorage.getItem('refreshToken');
var api = axios.create({
baseURL: `${process.env.REACT_APP_API}`,
headers: {
'Authorization': accessToken,
'Content-Type': 'application/json',
'Accept': 'application/json',
}
});
var apiNoHeaders = axios.create({
baseURL: `${process.env.REACT_APP_API}`
});
function getNewAccessToken(newRequest) {
apiNoHeaders.post(`auth/refresh?refreshToken=${refreshToken}`)
.then(res => {
localStorage.setItem('accessToken', res.data.accesToken)
localStorage.setItem('refreshToken', res.data.refreshToken)
api.defaults.headers['Authorization'] = res.data.accesToken;
newRequest._retry = true;
return axios(newRequest)
})
.catch(error => {
return Promise.reject(error);
})
}
api.interceptors.response.use(
response => response,
error => {
if (error.response) {
switch (error.response.status) {
case 401:
var newRequest = error.config;
getNewAccessToken(newRequest);
break;
case 403:
AUTH.logout(() => {
window.location.replace("/loggedOut");
});
default:
break;
}
}
throw error;
});
export default api;