axios interceptor로 refresh 하기
💻

axios interceptor로 refresh 하기

생성일
Jan 2, 2022 02:01 AM
태그
axios
axios 의 interceptor response를 사용해 액세스 토큰이 만료되면 리프레쉬 하는 로직을 쉽게 구현 할 수 있다.
 
전체 코드
import axios, { Axios, AxiosError } from "axios";

class API {
  api: Axios;

  constructor() {
    this.api = axios.create();

    this.setBaseURL();
    this.setAuthorization();
    this.setInterceptor();
  }

  setBaseURL() {
    this.api.defaults.baseURL = process.env.NEXT_PUBLIC_SERVER_URL;
  }

  setAuthorization() {
    if (typeof window !== "undefined") {
      const accessToken = window.localStorage.getItem("accessToken");
      const authorization = accessToken ? `Bearer ${accessToken}` : "";
      this.api.defaults.headers.common["Authorization"] = authorization;
    }
  }

  setInterceptor() {
    this.api.interceptors.response.use(
      (res) => res,
      async (error: AxiosError) => {
        const { config, response } = error;

        if (
          response?.status === 401 &&
          window.localStorage.getItem("accessToken")
        ) {
          const accessToken = await this.refresh();

          if (accessToken) {
            return axios({
              ...config,
              headers: { Authorization: `Bearer ${accessToken}` },
            });
          }
        }

        return Promise.reject(error);
      }
    );
  }

  async refresh() {
    try {
      const response = await this.api.post("/auth/refresh", {
        refreshToken: window.localStorage.getItem("refreshToken"),
      });
      const accessToken = response.data.value.accessToken;
      window.localStorage.setItem("accessToken", accessToken);
      this.setAuthorization();

      return accessToken;
    } catch {
      clearLocalstorage();

      return null;
    }
  }

  clear() {
    clearLocalstorage();
    this.setAuthorization();
  }
}

function clearLocalstorage() {
  window.localStorage.removeItem("accessToken");
  window.localStorage.removeItem("refreshToken");
}

// 이름을 뭘로 해야할지..
export const apiSetting = new API();
export const api = apiSetting.api;
 
this.api.interceptors.response.use(
  (res) => res,
  async (error: AxiosError) => {
    const { config, response } = error;

    if (
      response?.status === 401 &&
      window.localStorage.getItem("accessToken")
    ) {
      const accessToken = await this.refresh();

      if (accessToken) {
        return axios({
          ...config,
          headers: { Authorization: `Bearer ${accessToken}` },
        });
      }
    }

    return Promise.reject(error);
  }
);
this.api는 axios.create 로 만든 인스턴스이다.
this.api.interceptors.response.use() 메서드로 인터셉터를 등록 할 수 있는데, 첫번째 인자에는 요청이 성공했을 때 실행될 인터셉터이고, 두번째 인자로 요청이 실패했을 경우 실행될 인터셉터이다.
액세스 토큰 인증이 실패할 경우 서버에서 401 상태코드로 에러 응답을 보내는데, 에러응답 인터셉터에서 이 상태코드의 에러의 경우 토큰을 리프레시하고 다시 재요청을 보내면 된다.
 

Loading Comments...