axios Interceptors

axios 를 자세히 공부 중에 인터셉터 라는 기능을
공부해서 정리해 보았습니다.
인터셉터(Interceptors)란? then 또는 catch로 처리되기 전에 요청과 응답을 가로챌 수 있다.

 

API 요청을 할때마다 HTTP Authorization 요청 헤더에 토큰을 넣어줘야하는 경우가 생깁니다.

하지만 이러한 경우가 많이 발생할 경우 중복 코드가 발생하고 유지보수가 복잡해 지는 문제가 발생합니다.

사용자 지정 config 로 새로운 Axios 인스턴스를 생성하여 사용하면 더욱 편리하기 때문에 Axios 인스턴스를 기초로

설명하겠습니다.

 

적용해보기

Axios 인스턴스 생성하기

const instance = axios.create({
  baseURL: "www.text.com",
  timeout: 1000, // 요청이 timeout보다 오래 걸리면 요청이 중단됩니다.
});

요청 인터셉터 추가해보기

요청이 전달되기 전에 작업 수행, 요청 오류가 있는 작업 수행을 할 수 있는 2개의 콜백 함수를 받습니다.

이걸 이용해서 내가 원하는 요청 인터셉터를 만들어 줄 수 있습니다.

instance.interceptors.request.use(
  (config) => {
    // 클라이언트에 저장된 액세스 토큰을 가져옴
    const accessToken = getToken();

    // 토큰이 존재하고 유효한지 확인
    if (accessToken) {
      // 기존 헤더 유지하면서 새로운 헤더 추가
      config.headers = {
        ...config.headers, // 기존 헤더 유지
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${accessToken}`,
      };
    } else {
      console.warn('토큰이 존재하지 않거나 유효하지 않습니다.');
      // 필요에 따라 여기서 요청을 중단할 수 있음
      // 예: throw new Error('인증 토큰이 없습니다.');
    }

    return config;
  },
  (error) => {
    // 요청 설정 중 오류가 발생한 경우
    console.error('요청 인터셉터 오류:', error);
    return Promise.reject(error); // 오류를 그대로 반환하여 호출 측에서 처리할 수 있도록 함
  }
);

 

코드 설명

instance.interceptors.request.use

Axios 인스턴스에 요청 인터셉터를 추가합니다.

 

config.headers['Content-Type'] = 'application/json';

config.headers['Authorization'] = Bearer ${accessToken};

요청의 헤더에 Content-Type을 application/json으로 설정합니다.

요청 헤더에 Authorization 헤더를 추가하여, Bearer 토큰을 서버로 전송합니다.

이렇게 설정하면 내가 직접 설정하지 않아도 자동으로 토큰이 들어가게 됩니다.

 

return config;

config 객체는 Axios가 HTTP 요청을 보낼 때 사용하는 설정 정보입니다.

이 객체를 반환하지 않으면, Axios는 수정된 설정을 사용하지 못하고 요청을 보내지 못하게 됩니다.

따라서 config를 반환해야만 설정한 헤더와 함께 요청이 올바르게 서버로 전송됩니다.

 

return Promise.reject(error);

요청 설정 중에 오류가 발생했을 때, 이 오류를 호출된 쪽으로 전달해야 합니다.

이렇게 하면 요청을 보낸 곳에서 .catch() 블록을 통해 이 오류를 처리할 수 있습니다.

 

응답 인터셉터 추가해보기

응답 데이터가 있는 작업 수행, 응답 오류가 있는 작업 수행을 할 수 있는 2개의 콜백 함수를 받습니다.

이걸 이용해서 내가 원하는 응답 인터셉터를 만들어 줄 수 있습니다.

instance.interceptors.response.use(
  (response) => {
    // 404 에러는 보통 성공적인 응답으로 처리되지 않으므로 이 부분은 일반적으로 필요하지 않습니다.
    return response;
  },
  async (error) => {
    if (error.response?.status === 401) {
      // tokenExpired() - 토큰 만료 여부를 확인하는 임의로 만든 함수
      // tokenRefresh() - 토큰을 갱신해주는 임의로 만든 함수
      if (tokenExpired()) {
        try {
          await tokenRefresh(); // 토큰 갱신
        } catch (refreshError) {
          // 토큰 갱신 실패 시 추가적인 처리 필요
          return Promise.reject(refreshError);
        }
      }

      const accessToken = getToken();

      error.config.headers = {
        ...error.config.headers, // 기존 헤더 유지
        'Content-Type': 'application/json',
        Authorization: `Bearer ${accessToken}`,
      };

      try {
        const response = await axios.request(error.config); // 요청 재시도
        return response;
      } catch (retryError) {
        return Promise.reject(retryError); // 재시도 실패 처리
      }
    }

    return Promise.reject(error); // 기타 오류 처리
  }
);

 

코드 설명

instance.interceptors.response.use

Axios 인스턴스에 응답 인터셉터를 추가합니다.

 

error.config.headers = { 'Content-Type': 'application/json', Authorization: `Bearer ${accessToken}`, };

다시 headers 를 새롭게 가져온 토큰으로 재설정 해줍니다.

 

여기까지 설정하면 이제부터는 마음대로 커스텀 하면서 만드시면 될 것 같습니다.

아주 기본적인 부분을 설명한 느낌이라 더 공부하고 싶으시다면 여러 블로그를 참고하시면 좋을 것 같습니다!!

'라이브러리' 카테고리의 다른 글

Tanstack Query  (4) 2024.10.02
Zustand  (2) 2024.09.25
Jotai  (1) 2024.08.24
React Intersection Observer  (0) 2024.08.20
React hook form  (0) 2024.07.26