본문 바로가기

React

React: axios interceptor를 통해 request, response를 미들웨어 처리

728x90
반응형

Axios.interceptors.request

Axios.interceptors.response

 

request를 보내는 첫 단계와, response를 받는 첫 단계에서

axios interceptor를 통해 미들웨어처럼 로직 핸들링하기

  - access token을 refresh token을 통해 자동으로 갱신하는 로직에 활용

    (refresh token 또한 만료시에는 Home으로 redirect)

 

// src/api.ts

axiosInstance.interceptors.request.use(
  (config) => {
    const {access_token, refresh_token, access_token_expire_at, refresh_token_expire_at} = store.getState().token;
    let accessToken = access_token;
    let refreshToken = refresh_token;

    if (!access_token_expire_at || !refresh_token_expire_at || !accessToken || !refreshToken) {
      return config;
    }

    if (!config.headers["Authorization"]) {
      axiosInstance.defaults.headers.common["Authorization"] = 'Bearer ' + accessToken;
      config.headers["Authorization"] = `Bearer ${accessToken}`;
    }

    return config;
  },

  (error) => Promise.reject(error)
);


axiosInstance.interceptors.response.use(
  (response) => {
    return response;
  },

  async (error) => {
    const originalRequest = error.config;
    if (error.response.status === 401) {
      const refreshToken = store.getState().token.refresh_token;
      if (!refreshToken) {
        await handleLogoutAndRedirect();
        return Promise.reject(error);
      }

      try {
        const response = await refreshAccessToken(refreshToken);
        const { access_token } = response;
        axiosInstance.defaults.headers.common["Authorization"] = 'Bearer ' + access_token;
        originalRequest.headers["Authorization"] = 'Bearer ' + access_token;
        store.dispatch(setCredentials(response));  
        return axiosInstance(originalRequest);
      } catch (refreshError) {
        await handleLogoutAndRedirect();
      }
    }
    return Promise.reject(error);
  }
);

 

 

interceptors.request.use

  -  redux store에 access token이 있는 경우 request header에 토큰 추가하여 request 요청

 

interceptors.response.use

  - 일반 response (에러 없는 경우)

    -> 그냥 response return

 

  - 401 error를 반환받은 경우

    -> refresh token을 store에서 가져온 후  refresh token을 활용해

        access token을 재발급 받는 refreshAccessToken api 사용

       -> 정상 진행시

           access_token을 global로 사용될 axiosInstance headers에 포함,

           오류가 발생했던 request를 다시 한번 request를 진행할 originalRequest의 headers에도 access_token을 포함

           store에도 token 정보 저장

          -> error가 났던 request를 토큰을 갱신하여 재요청

       -> 오류 발생시

          Logout과 Redirect 진행 (해당 부분에 대한  상세 로직은 아래 링크 참조)

          https://taltal-dev-note.tistory.com/347

 

 

* 해당 커밋 내역

https://github.com/Junanjunan/g6_react/commit/d2be1df667903c5720da5097a8540d579aeb3501

https://github.com/Junanjunan/g6_react/commit/c676b570d9b20b2a5a1fb5bbfa669a96798f66e5

https://github.com/Junanjunan/g6_react/commit/4586b0c0ff89ce654c4acd01321b15e99455c300

https://github.com/Junanjunan/g6_react/commit/707f2d4ec8620d1a3072bc0769672511939407be

728x90
반응형