如何在React中使用AXIOS运行令牌刷新机制?

时间:2020-06-20 15:32:47

标签: reactjs axios

我有一个带有登录组件的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;

0 个答案:

没有答案