본문 바로가기
    개발/React

    axios interceptors

    by 지미의 생각 2023. 8. 27.

    axios interceptors 자체는 토큰 재갱신에서 잠깐 봤지만 그 땐 다른 기능들이 더 급하여 잠시 미루고 useEffect로만 토큰 재갱신을 했었으나

    api 통신에서 공통된 헤더를 묶고,
    react-query 사용시 페이지에서 직접적으로 api를 사용하고 싶지 않아 (분리하고 싶어서) 다시 연구하던중
    axios interceptors로 다시 돌아가게 되어 작업을 하게 되었다.

    // import { TokenRefresh } from "api/auth";
    import axios from "axios";
    import { showToast } from "components/toast/showToast";
    import { ROOT_API } from "constants/api";
    import store from "store";
    import { SET_TOKEN, refreshAccessToken, tokenSlice } from "store/Auth";
    
    const apiInstance = axios.create({
      baseURL: "루트 도메인",
      headers: {
        "Content-Type": "application/json",
      },
      timeout: 5000,
    });
    
    // api를 요청하기전에 실행. axios로 지정한다면 axios요청하기 전에 실행.
    apiInstance.interceptors.request.use(
      async (config) => {
        const accessToken = store.getState().authToken.accessToken;
        const refreshToken = localStorage.getItem("dtrtk");
        // console.log("인터셉터 토큰", accessToken);
        if (accessToken) {
          config.headers["X-AUTH-TOKEN"] = `${accessToken}`;
          return config;
        }
        // if (!accessToken && refreshToken) {
        //   showToast("error", "회원 정보가 만료되었습니다.");
        //   return config;
        // }
        return config;
      },
      (error) => {
        return Promise.reject(error);
      }
    );
    
    // 요청이 완료된후
    apiInstance.interceptors.response.use(
      (response) => {
        // console.log("인터셉터 re", response.data);
        // if (response.status === 200) {
        //   console.log("Request succeeded!");
        // }
        // if (response.status !== 200) {
        //   console.log("dd");
        // }
        const res = response.data;
        return res;
      },
      async function (err) {
        if (err.response && err.response.status === 401) {
          // 토큰 재발급 요청
          const data = await axios.post(`${ROOT_API}/token/refresh`, {
            refreshToken: localStorage.getItem("dtrtk"),
            headers: {
              accept: "*/*",
              "Content-Type": "application/json",
            },
          });
    
          // store 갱신
          store.dispatch(
            SET_TOKEN({
              accessToken: `${data.data.accessToken}`,
            })
          );
    
          // 헤더에 담긴 토큰 값 변경
          err.config.headers = {
            "Content-Type": "application/json",
            "X-AUTH-TOKEN": `${data.data.accessToken}`,
          };
    
          // 재요청
          const originalResponse = await axios.request(err.config);
          return originalResponse.data;
        }
        return Promise.reject(err);
      }
    );
    
    export default apiInstance;
    

    댓글