Reactjs 重新发送使用过期令牌发出的请求将导致开发人员工具中处于挂起状态

Reactjs 重新发送使用过期令牌发出的请求将导致开发人员工具中处于挂起状态,reactjs,axios,jwt,Reactjs,Axios,Jwt,我有一个react应用程序,我正在尝试实现JWT 我使用的是axios拦截器,在该拦截器中,我捕获服务器由于令牌过期而返回的状态401,将刷新令牌发送到服务器,在客户端接收新的访问令牌,然后重新发送原始失败的请求 我面临的问题是,当我重新发送原始失败的请求时,状态在开发人员工具的“网络”选项卡中显示为“永远挂起”。最初失败的请求是POST请求,当我检查数据库时,它已更新。那么为什么它在开发者工具中显示挂起状态呢 这是我的axios拦截器代码 import axios from 'axios' /

我有一个react应用程序,我正在尝试实现JWT

我使用的是
axios
拦截器,在该拦截器中,我捕获服务器由于令牌过期而返回的状态401,将刷新令牌发送到服务器,在客户端接收新的访问令牌,然后重新发送原始失败的请求

我面临的问题是,当我重新发送原始失败的请求时,状态在开发人员工具的“网络”选项卡中显示为“永远挂起”。最初失败的请求是POST请求,当我检查数据库时,它已更新。那么为什么它在开发者工具中显示挂起状态呢

这是我的axios拦截器代码

import axios from 'axios'
// import refreshToken from '../src/Store/refreshToken'
import { store } from '../src/index'
import { removeAuth } from '../src/Store/actions/authAction'

const api = axios.create({
    baseURL: process.env.REACT_APP_SERVER
}) 

function createAxiosResponseInterceptor(axiosInstance) {
    axiosInstance.interceptors.request.use(function (config) {
        const token = localStorage.getItem('token');
        if (token){
            config.headers.Authorization = token;
            }
        return config
        }
    )

    axiosInstance.interceptors.response.use(
        response => {
            return response;
        },
        error => {
            var errorStatus = error.response.status;
           
            
            if (errorStatus === 401){                                   // status 401 is used when token is expired
                let cookies = document.cookie
                let refresh = cookies.split("refresh=")[1].split(';')[0]
                if(!sendRefreshToken(refresh, error)) {
                    store.dispatch(removeAuth({isLoggedIn: false}));
                    localStorage.setItem('token', '');
                    document.cookie = "refresh=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
                }
            }
            return error
        }
    );
}

function sendRefreshToken(refreshToken, error) {
    let result = api.post('/refresh', {
                        refreshToken: refreshToken
                    })
                    .then(response => {
                        if (response.data.success && response.data.message === "new access token set") {
                            localStorage.setItem('token', response.data.newToken)
                            api({                                               // Here I am resending the failed request.
                                method: error.response.config.method,
                                url: error.response.config.url,
                                data: JSON.parse(error.response.config.data)
                            }).then(response => {
                                console.log(response)
                                return true
                            })
                            .catch(error => {
                                console.log(error)
                                return false
                            })
                        }
                    })
                    .catch(error => {
                        console.log(error)
                        return false
                    })
    return result
}



createAxiosResponseInterceptor(api);

export default api;  

如果你发现代码有什么问题,请告诉我。让我知道这是否是正确的方法。开放以提供更多奖励积分。

请考虑本文以供参考。


对答案进行一些修改后,GET请求将成功重新发送,但POST请求在开发者工具中显示为
cancelled
。saveRefreshToken(jsonRefreshResponse.data.refreshToken);刷新时应为saveJwtToken no,因为如果不更改,则发送相同的令牌,对吗?
import axios from 'axios'
// import refreshToken from '../src/Store/refreshToken'
import { store } from '../src/index'
import { removeAuth } from '../src/Store/actions/authAction'

const api = axios.create({
    baseURL: process.env.REACT_APP_SERVER
})

function createAxiosResponseInterceptor(axiosInstance) {
    axiosInstance.interceptors.request.use(function (config) {
        const token = localStorage.getItem('token');
        if (token){
            config.headers.Authorization = token;
            }
        return config
        }
    )

    axiosInstance.interceptors.response.use(
        response => {
            return response;
        },
        error => {
            var errorStatus = error.response.status;

            const originalRequest = error.config;
          
            if (
              error.response.status === 401 &&
              !originalRequest._retry
            ) {

              originalRequest._retry = true;
              return api
              .post('/refresh', {
                refreshToken: getRefreshToken()
            })

                .then((jsonRefreshResponse) => {
                  if (jsonRefreshResponse.status === 200) {


                    // 1) put token to LocalStorage
                    saveRefreshToken(
                      jsonRefreshResponse.data.refreshToken
                    );
                    // 2) Change Authorization header

                    const newAccessToken = getJwtToken();
                  
                    setAuthHeader(newAccessToken);


                    // 3) return originalRequest object with Axios.
                 //   error.response.config.headers[
                 //     "Authorization"
                 //   ] = `Bearer ${newAccessToken}`;
                    setAuthHeader(newAccessToken)
                    return axios(error.response.config);
                  }
                })
                .catch((err) => {
                  console.warn(err);
                })

              }

              if (error.config) {
                console.log(error.config);
                return Promise.reject();
              }
        }
    );
}

export const setAuthHeader = (token) => {
  api.defaults.headers.common["Authorization"] = `Bearer ${token}`;
};



createAxiosResponseInterceptor(api);

export default api;

//These methods could be in separate service class
const getJwtToken=()=> {
  return localStorage.getItem("token");
}
const getRefreshToken=() =>{
  return localStorage.getItem("refreshToken");
}
const saveJwtToken=(token)=> {
  localStorage.removeItem("token");
  localStorage.setItem("token", token);
}
const saveRefreshToken=(refreshToken)=> {
  localStorage.setItem("refreshToken", refreshToken);
}