Глобальный перехватчик Axios для обновления токена - PullRequest
2 голосов
/ 07 ноября 2019

ОК, так что это моя третья стена, с которой я столкнулся с этой проблемой, во-первых, вот мой конфигурационный файл axios

import axios from "axios";
import { withRouter } from "react-router-dom";

const instance = axios.create({
  baseURL: process.env.REACT_APP_API,
  headers: {
    "content-type": "application/json"
  },
  responseType: "json"
});
function pushToLogin() {
  this.props.history.push("/");
}
function createAxiosResponseInterceptor(axiosInstance) {
  const interceptor = axiosInstance.interceptors.response.use(
    response => response,
    error => {
      // Reject promise if usual error
      console.log(error);
      if (error.response.status !== 401) {
        return Promise.reject(error);
      }
      /*
       * When response code is 401, try to refresh the token.
       * Eject the interceptor so it doesn't loop in case
       * token refresh causes the 401 response
       */
      axiosInstance.interceptors.response.eject(interceptor);
      return axiosInstance
        .post("token/refresh/", {
          refresh: localStorage.getItem("refreshToken")
        })
        .then(response => {
          localStorage.setItem("accessToken", response.data.access);
          error.response.config.headers["Authorization"] =
            "Bearer " + response.data.access;
          return axiosInstance(error.response.config);
        })
        .catch(error => {
          localStorage.setItem("accessToken", null);
          localStorage.setItem("refreshToken", null);
          pushToLogin();
          return Promise.reject(error);
        })
        .finally(createAxiosResponseInterceptor(this));
    }
  );
}

createAxiosResponseInterceptor(instance);

export default withRouter(instance);

Что я хочу, так это: Запрос получает 401> Получить новый токен исохраняем его> повторяем запрос> если все идет хорошо, то хорошо, если нет, возвращается нормальная ошибка.

Что происходит: запрос получает 401> получает новый токен и сохраняет его> повторяет запрос> если это хорошо, мывсе в порядке, если нет, то это последний блок перехвата на моем перехватчике, который, как мне показалось, предназначался специально для запроса refreshToken, или, по крайней мере, именно этого я и хочу.

Дополнительный вопрос:Я хотел бы нажать для входа в систему при ошибке refreshToken, как вы можете видеть, я пытаюсь использовать withRouter для этого, но я cannot read props of undefined на этой линии, так что это еще одна проблема.

Большое спасибо!

Редактировать: Даже если этот запрос был выполнен другими способами, я бы хотел узнать, что не так с моим кодом, чем узнать чужой.

1 Ответ

0 голосов
/ 11 ноября 2019

Я перешел на использование пакета axios-auth-refresh , код конфигурации, который я использую, находится здесь:

import axios from "axios";
import createAuthRefreshInterceptor from "axios-auth-refresh";

const instance = axios.create({
  baseURL: process.env.REACT_APP_API,
  headers: {
    "content-type": "application/json"
  },
  responseType: "json"
});
const refreshAuthLogic = failedRequest =>
  instance
    .post("token/refresh/", {
      refresh: localStorage.getItem("refreshToken")
    })
    .then(tokenRefreshResponse => {
      localStorage.setItem("accessToken", tokenRefreshResponse.data.access);
      failedRequest.response.config.headers["Authorization"] =
        "Bearer " + tokenRefreshResponse.data.access;
      return Promise.resolve();
    })
    .catch(error => {
      console.log("refresh fail");
      localStorage.setItem("accessToken", null);
      localStorage.setItem("refreshToken", null);
      //pushToLogin();
      return Promise.reject(error);
    });
createAuthRefreshInterceptor(instance, refreshAuthLogic);

export default instance;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...