Axios 拦截器刷新多个请求的访问令牌

12
我会在收到返回状态码为401时调用刷新令牌并取消此前的HTTP请求。在刷新令牌响应后,我需要重新发起之前的请求。
示例: 登录 -> 1小时后 -> 调用产品 -> 401 -> 调用刷新令牌 -> 调用产品
我尝试使用这个链接一个链接 并查看这个链接一个链接 但都不行。
捕获401错误。
setInterceptors = () => {
        axios.interceptors.response.use(
            response => {
                return response;
            },
            err => {
                return new Promise((resolve, reject) => {
                    if (err.response.status === 401 && err.config && !err.config.__isRetryRequest) {

                        const originalRequest = err.config;

                        this.emit('onAutoLogin', originalRequest);
                    }
                    // throw err;
                });
            }
        );
    };

调用我的动作

jwtService.on('onAutoLogin', originalRequest => {
                    jwtService
                        .signInWithToken()
                        .then(res => {
                            if (res.access_token) {
                                originalRequest.headers['Authorization'] = 'Bearer ' + res.access_token;


Axios.request(originalRequest).then(response => {
                                    store.dispatch({
                                        type: ** MY PROBLEM İS HERE **
                                        payload: response.data
                                    });
                                });
                            }
                        })
                        .catch(err => {
                            jwtService.setSession(null); 
});

除了“它不起作用”以外,你能否更具体地说明问题是什么?有出现错误吗?只是没有分发该动作吗?已经分发该行动但没有得到处理吗?在调试方面你尝试过什么? - Drew Reese
你的 originalRequest 真的是整个 err.config 对象吗?还是你想要解构它? - Drew Reese
刷新令牌正在工作。originalRequest 真的是整个 err.config 对象。我还使用 originalRequest 调用了最后一个 http 操作。但我无法保持触发返回数据所需的操作(类型、有效载荷)。 - Burak SARI
是的,我看到了在 type 所在行的注释。问题是什么?“无法保持操作...”的含义不清楚。 - Drew Reese
我无法获取Redux中的最后一个操作。 - Burak SARI
从你的代码片段中并不清楚 store 是否在作用域内或者是否已经定义,我们也不知道你的 action/reducer 对是什么样子的,而且你还没有说明 哪里 出了问题。有错误吗?堆栈跟踪?肯定有更多信息可用于帮助调试。能否创建一个可共享的 codesandbox 来重现你的问题,以便其他人可以看到你所看到的? - Drew Reese
1个回答

32

使用这个链接,我能够在不触发redux store的情况下解决问题。

let isRefreshing = false;
 let failedQueue = [];

       const processQueue = (error, token = null) => {
            failedQueue.forEach(prom => {
                if (error) {
                    prom.reject(error);
                } else {
                    prom.resolve(token);
                }
            });

            failedQueue = [];
        };

axios.interceptors.response.use(
            response => {
                return response;
            },
err => {
                const originalRequest = err.config;

                if (err.response.status === 401 && !originalRequest._retry) {
                    if (isRefreshing) {
                        return new Promise(function(resolve, reject) {
                            failedQueue.push({ resolve, reject });
                        })
                            .then(token => {
                                originalRequest.headers['Authorization'] = 'Bearer ' + token;
                                return axios(originalRequest);
                            })
                            .catch(err => {
                                return Promise.reject(err);
                            });
                    }

                    originalRequest._retry = true;
                    isRefreshing = true;

                    return new Promise(function(resolve, reject) {
                        axios
                            .post('/fooUrl/refreshToken', {
                                refreshToken: "fooToken"})
                            .then(({ data }) => {
                                axios.defaults.headers.common['Authorization'] = 'Bearer ' + data.fooToken;
                                originalRequest.headers['Authorization'] = 'Bearer ' + data.fooToken;
                                processQueue(null, data.fooToken);
                                resolve(axios(originalRequest));
                            })
                            .catch(err => {
                                processQueue(err, null);
                                store.dispatch(showMessage({ message: 'Expired Token' }));

                                reject(err);
                            })
                            .then(() => {
                                isRefreshing = false;
                            });
                    });
                }

                return Promise.reject(err);
            }
        );

伟大的人,谢谢 :) - Padi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接