axios intercepter

Eugenius1st·2023년 11월 20일
0

axios intercepter

then 또는 catch로 처리되기 전에 요청과 응답을 가로챌수 있습니다.

// 요청 인터셉터 추가하기
axios.interceptors.request.use(function (config) {
    // 요청이 전달되기 전에 작업 수행
    return config;
  }, function (error) {
    // 요청 오류가 있는 작업 수행
    return Promise.reject(error);
  });

// 응답 인터셉터 추가하기
axios.interceptors.response.use(function (response) {
    // 2xx 범위에 있는 상태 코드는 이 함수를 트리거 합니다.
    // 응답 데이터가 있는 작업 수행
    return response;
  }, function (error) {
    // 2xx 외의 범위에 있는 상태 코드는 이 함수를 트리거 합니다.
    // 응답 오류가 있는 작업 수행
    return Promise.reject(error);
  });

나중에 필요할때 인터셉터를 제거할 수 있습니다.

const myInterceptor = axios.interceptors.request.use(function () {/*...*/});
axios.interceptors.request.eject(myInterceptor);

커스텀 인스턴스에서도 인터셉터를 추가할 수 있습니다.

const instance = axios.create();
instance.interceptors.request.use(function () {/*...*/});

1. JWT + 로컬스토리지 저장 방식일 때 구현

JWT 인증방식 로그인 + 토큰 로컬스토리지에 저장

특정 프로젝트에서 밑과 같이 구현했다.

JWT토큰 전달,갱신방식
전달방식 - headers로 토큰 전달
갱신방식 - Access 토큰이 만료되면 Refresh 토큰을 요청에 같이 전달. 응답으로 갱신된 토큰 받았음.

요청 전 interceptors

access토큰 있으면 JWT 디코딩해서 만료시간 검사
만료됐으면 만료된 access + refresh 토큰 같이 헤더에 담아서 요청
만료안됐으면 access만 요청 전 헤더에 담는 작업 수행

응답 전 interceptors

access 토큰 만료돼서 응답헤더에 새로운 access토큰이 받아지면
만료된 access토큰 localStorage에서 삭제 후 새 토큰으로 교체
이후 요청 헤더에 새 access토큰을 담기

구현코드
import axios, { AxiosRequestConfig, AxiosResponse } from 'axios';
import { ACCESS_EXP_MESSAGE, CheckJWTExp } from 'utils/CheckJwtExp';
import {
  getLocalStorage,
  removeLocalStorage,
  setLocalStorage,
} from './localStorage';

axios.defaults.withCredentials = true;

/** 1. 요청 전 - access토큰있는데 만료되면 refresh토큰도 헤더담아서 요청보내기 */
axios.interceptors.request.use(
  (config: AxiosRequestConfig) => {
    const accessToken = getLocalStorage('access_token');
    const refreshToken = getLocalStorage('refresh_token');
    if (accessToken) {
      /** 2. access토큰 있으면 만료됐는지 체크 */
      if (CheckJWTExp() === ACCESS_EXP_MESSAGE) {
        /** 3. 만료되면 만료된 access, refresh 같이 헤더 담아서 요청 */
        config.headers!.Authorization = `${accessToken}`;
        config.headers!.Refresh = `${refreshToken}`;
      } else {
        config.headers!.Authorization = `${accessToken}`;
      }
    }
    return config;
  },
  (error) => Promise.reject(error)
);

/** 4. 응답 전 - 새 access토큰받으면 갈아끼기 */
axios.interceptors.response.use(
  async (response: AxiosResponse) => {
    if (response.headers.authorization) {
      const newAccessToken = response?.headers?.authorization;
      removeLocalStorage('access_token'); // 만료된 access토큰 삭제
      setLocalStorage('access_token', newAccessToken); // 새걸로 교체
      response.config.headers = {
        authorization: `${newAccessToken}`,
      };
    }
    return response;
  },
  (error) => {
    //응답 200 아닌 경우 - 디버깅
    return Promise.reject(error);
  }
);

참고

profile
최강 프론트엔드 개발자가 되고싶은 안유진 입니다

0개의 댓글