[Axios] Axios Interceptor 적용하기

문지은·2023년 9월 17일
post-thumbnail

백엔드와 통신시 인증이 필요한 경우 아래와 같이 헤더에 토큰을 넣어서 메서드를 요청해야 한다.

const response = await axios({
  method: 'GET',
  url: 'url',
	headers: {
      Authorization: `Bearer ${token}`,
  },
});

인증이 필요한 모든 axios 요청에서 직접 헤더를 넣는 귀찮은 반복 작업을 axios interceptor를 이용하여 해결할 수 있다.

Axios Interceptor

  • axios interceptor는 애플리케이션에서 처리하기 전에 Axios 라이브러리에서 수행한 HTTP 요청 또는 응답을 가로채고 수정하는 데 사용할 수 있는 기능
  • 요청에 인증 헤더 추가, 오류 처리 또는 요청 및 응답 로깅과 같은 다양한 용도로 사용할 수 있다.
  • axios interceptor를 사용하면 모든 요청 또는 응답에서 동일한 코드를 반복하지 않아도 되어서 코드가 더 간결해지고 유지 관리가 쉬워진다.

Axios 인스턴스 만들기

  • 사용자 지정 config로 새로운 axios 인스턴스를 만들 수 있다. (공식문서 참고)
const instance = axios.create({
  baseURL: 'https://some-domain.com/api/',
  timeout: 1000,
  headers: {'X-Custom-Header': 'foobar'}
});
  • baseURL
    • 엔드포인트의 기본 URL로, axios 인스턴스에서 보내는 모든 요청의 기본 URL을 지정
    • 요청을 보낼 때 상대적인 URL만 사용하면 해당 baseURL이 자동으로 앞에 붙게 됨.
  • timeout
    • 요청에 대한 타임아웃을 설정
    • 이 시간(밀리초) 이내에 서버로부터 응답을 받지 못하면 요청이 실패하고 에러발생
  • headers
    • HTTP 헤더를 나타내는 객체로, 요청 헤더에 추가할 사용자 지정 헤더를 지정하는 데 사용

Interceptors request 작성

  • request가 전송되기 전에 실행되는 기능
  • request 구성 또는 헤더를 수정하고, 인증 토큰 또는 기타 데이터를 추가하고, 서버에 요청을 보내기 전에 다른 작업을 수행할 수 있다.
// 요청 인터셉터 추가하기
axios.interceptors.request.use(
	(config) => {
    // 요청이 전달되기 전에 작업 수행
    return config;
  },
  (error) => {
    // 요청 오류가 있는 작업 수행
    return Promise.reject(error);
  });
  • axios 요청시 헤더에 토큰을 넣어 요청하는 interceptors request 예시
    • 토큰은 세션 스토리지에 저장되어 있다고 가정
axiosInstance.interceptors.request.use(
	// 요청이 전달되기 전에 헤더에 토큰 넣기
  (config) => {
    const token = sessionStorage.getItem('token');
    if (token) {
      const newConfig = { ...config };
      newConfig.headers.Authorization = `Bearer ${token}`;
      return newConfig;
    }
    return config;
  },
  (error) => {
    // 요청 오류가 있는 작업 수행
    return Promise.reject(error);
  },
);

Interceptors reponse 작성

  • response를 받은 후 실행되는 기능
  • response가 호출 코드로 다시 전달되기 전에 response 데이터를 수정하거나, 오류를 처리하거나, 정보를 기록하거나, 다른 작업을 수행할 수 있다.
// 응답 인터셉터 추가하기
axios.interceptors.response.use(
	(response) => {
    // 2xx 범위에 있는 상태 코드는 이 함수를 트리거 합니다.
    // 응답 데이터가 있는 작업 수행
    return response;
  }, 
	(error) => {
    // 2xx 외의 범위에 있는 상태 코드는 이 함수를 트리거 합니다.
    // 응답 오류가 있는 작업 수행
    return Promise.reject(error);
  });
  • 토큰 만료 등으로 인증이 불가능한 경우 메인페이지로 이동하도록 하는 interceptors response 사용 예시
axiosInstance.interceptors.response.use(
  (response) => {
    return response;
  }, 
  (error) => {
    const statusCode = error.response?.status;
    if (statusCode === 401) {
      error.response.statusText = 'Unauthorized';
      error.response.status = 401;
      navigate('/');
    }
    return Promise.reject(error);
  }
);

axios Instance 사용하기

  • 위 예시들을 종합한 axios Intance 코드는 다음과 같다.

axiosInstance.js

// 인스턴스 생성
const instance = axios.create({
  baseURL: 'URL',
});

// 요청 인터셉터
axiosInstance.interceptors.request.use(
	// 요청이 전달되기 전에 헤더에 토큰 넣기
  (config) => {
    const authToken = sessionStorage.getItem('token');
    if (authToken) {
      const newConfig = { ...config };
      newConfig.headers.Authorization = `Bearer ${token}`;
      return newConfig;
    }
    return config;
  },
  (error) => {
    // 요청 오류가 있는 작업 수행
    return Promise.reject(error);
  },
);

// 응답 인터셉터
axiosInstance.interceptors.response.use(
  (response) =>
    return response;
  }, 
  (error) => {
    const statusCode = error.response?.status;
    if (statusCode === 401) {
      error.response.statusText = 'Unauthorized';
      error.response.status = 401;
      navigate('/');
    }
    return Promise.reject(error);
  }
);
  • axios 요청시 axios 대신에 axiosInstance 사용하기
    • 이제 매번 헤더에 토큰을 넣을 필요가 없다!
import axiosInstance from '../../config/axiosInstance.js'

async function getUser() {
  try {
    const response = await axios({
		  method: 'GET',
		  url: '/api/user',
		});
    console.log(response);
  } catch (error) {
    console.log(error);
  }
}

References

profile
코드로 꿈을 펼치는 개발자의 이야기, 노력과 열정이 가득한 곳 🌈

0개의 댓글