Axios Interceptors 기능 구현

민토의 블로그·2023년 3월 30일
8
post-thumbnail

Axios Interceptor 로직을 구현하면서 들었던 고민에 대해서 정리한 글 입니다.
Axios Interceptor의 사용 방법에 대해서 알고 싶으신분한테는 적절한 글은 아닙니다.

문제 상황

엘리스 팀 프로젝트 진행중 로그인 로직을 구현하기전에 많은 고민이 생겼다. 사용자가 로그인을 하고 각 페이지마다 사용자의 로그인을 유지하는 부분에 대해서 고민이 됐다.

  1. 로그인을 유지하려면 매 요청마다 요청 헤더에 jwt를 담아서 서버로 보내야 하는데 이 작업을 매번 api 요청마다 해주기에는 팀원들의 코드에 해당 코드를 반복적으로 적어줘야 해서 비효율적이라는 생각이 들었다.

  2. 프로젝트 구조가 커져가면서 요청헤더에 jwt 토큰을 넣어줘야 하는 요청이 있고 안 넣어줘도 되는 요청이 있을때 jwt 토큰을 넣는걸 놓쳐서 생기는 문제도 생길 수 있기 때문에 이를 한번에 처리가 가능한지에 대한 고민이 됐다.

  3. jwt가 만료 되었거나 적절한 jwt가 아닐경우에 에러 처리도 마찬가지로 각 api 요청마다 넣어주기에 비효율적이라는 생각이 들었다.

그럼 어떻게 해야할까?

프로젝트 외부에 utils 폴더에서 함수를 작성하면 어떨까 라는 생각이 들었다.
Axios 요청을 할 때마다 무조건 해당 함수를 호출하고 나서 return이 true라면 원하는 요청을 하도록 구현하면 어떨까라는 생각을 했다.

하지만 이 방법은 코드의 중복은 조금 더 줄일 수 있지만 마찬가지로 모든 팀원들이 컴포넌트마다 api 요청을 할 때 해당 로직을 호출해서 사용해줘야 한다.

그리고 해당 로직을 사용하는 컴포넌트와 사용하지 않는 컴포넌트가 나뉘어 있는데 이를 문서로 관리하기에는 시스템적으로 막는게 아니기 때문에 예상치 못한 실수가 발생할 수 있다는 단점이 있을 수도 있다.

Axios Intercepter 사용 이유?

이슈를 해결하기 위해 해결책을 찾다가 Axios 라이브러리에 Intercepter 기능에 대해서 찾게 됐다. (https://axios-http.com/kr/docs/interceptors)

말 그대로 클라이언트와 서버간에 요청 응답을 중간에 가로채서 추가적인 처리를 먼저 하도록 해주는 방법이다.

서버로 부터 어떤 요청을 하기전에 해당 로직을 작성해 놓으면 매 요청마다 먼저 헤더에 jwt를 보내 유효성 검사를 하는게 가능해졌다.

이로인해 코드의 중복없이 하나의 파일에서 로직을 작성해서 관리하는게 가능해졌다.

마찬가지로 jwt를 포함하고 싶지 않은 라우터도 작성할 수 있었고 jwt 유효성 검사에서 실패한 경우의 에러 처리도 한번에 하는게 가능해졌다.

그리고 추가적으로 baseURL을 설정해 루트 경로에 대한 것도 하나의 파일에서 관리하는게 가능해졌고

응답받는 데이터도 서버로 부터 받아온 status 상태 코드로 부터 추가적인 처리가 가능해졌다.

이 방법은 특히 팀 프로젝트에서 도움이 많이 되는거 같다. 모든 처리를 해당 로직에서 대신하니깐 개발자들은 해당 로직을 신경쓰지 않고 내 코드에 자신감을 가지고 api 요청을 보내는 로직을 작성할 수 있기 때문에 효율적으로 개발에 시간을 할애할 수 있다는 큰 장점이 매력으로 다가왔다.

Axios Interceptor는 어떻게 사용할까?

공식 문서를 보면 대부분의 사용방법에 대해서 이해할꺼라고 생각한다.

import axios from 'axios';

const instance = axios.create({
  baseURL: '(api주소)'
});

const excludeTokenUrl = ['/login', '/signUp', '/nonUserLogin', '/nonUserOrderLookUp'];

instance.interceptors.request.use(
  (config) => {
    const token = localStorage.getItem('Auth');

    try {
      if (!excludeTokenUrl.includes(config.url) && token) {
        config.headers['Authorization'] = `Bearer ${token}`;
      }

      return config;
    } catch (error) {
      console.log('jwt 토큰이 없거나 jwt 토큰의 유효기간이 지났습니다.');
    }
    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);

프로젝트에서 작성했던 요청부분 예시 코드이다.

위에서 작성한 interceptor 코드를 api 요청하고자 하는 파일에서 import 후에 axios.get 대신 사용해주면 된다.

profile
블로그 이전했습니다. https://frontend-minto.tistory.com/

0개의 댓글