Next.js에서 axios interceptors 적용하는 방법 + rewrite

JS/Next.js · 2024. 6. 4. 17:48
728x90

한참 작업중 API가 무수히 쌓이면서 공통적으로 들어가는 header가 있었다.

로그인했을때 AccessToken과 Content-type을 넣는 부분이 계속 쌓이다보니 중복되는 코드가 있었고

찾아보니 axios에 intercepors로 hook화 시킬 수 있었다.

 

axios 공홈에 가면 intercepters를 적용하는 방법이 친히 나와있다.

https://axios-http.com/kr/docs/interceptors

 

인터셉터 | Axios Docs

인터셉터 then 또는 catch로 처리되기 전에 요청과 응답을 가로챌수 있습니다. axios.interceptors.request.use(function (config) { return config; }, function (error) { return Promise.reject(error); }); axios.interceptors.response.use(f

axios-http.com

// 요청 인터셉터 추가하기
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);
  });

 

예시로 준 코드.

그대로 적용해 보았으나 문제는...

accessToken값을 auth.js를 써서 session에 담아뒀는데

걔를 불러올수가 없었다. 그러다 찾아보니 clientAPI.ts에서 호출하지 말고

ClientAPI.tsx를 만들어서 layout.tsx에 가서 붙여줬다.

그러고

"use client";

import axios from "axios";
import { signIn, useSession } from "next-auth/react";
import { useEffect } from "react";

const instance = axios.create({
  baseURL: "/APIURL",
});

function AxiosInterceptor({ children }: any) {
  const AccessToken = useSession().data?.accessToken;
  const refreshToken = useSession().data?.refreshToken;
  useEffect(() => {
    instance.interceptors.request.use(
      async (config) => {
        if (AccessToken) {
          config.headers["Content-Type"] = "application/json";
          config.headers["Authorization"] = `Bearer ${AccessToken}`;
        }
        return config;
      },
      (error) => {
        if (refreshToken) {
          signIn("credentials", {
            code: refreshToken,
            type: "refresh-token",
          });
        }
        return Promise.reject(error);
      }
    );
  }, [AccessToken]);
  return children;
}

export default instance;
export { AxiosInterceptor };

 

요러고 넣어줌.

에러날 경우 accessToken이 만기된거니 저기서 refreshToken 처리를 해줬다.

그러고 api 불러올때는 axios대신 만든버전인 instance를 써준다

export const getArticle = async (id: string | string[], board: string) => {
  try {
    const res = await instance.get(`/article/${board}/${id}`);
    return res.data.result;
  } catch (err: any) {
    alert(err.response.data.errorDescription);
    return false;
  }
};

요런식으로.. 

그럼 헤더값에 accessToken이랑 Content-type이 알아서 들어가지고

 apiurl 도메인도 알아서 들어가진다.

참고로 /APIURL은 그냥 process.env.NODE_API_URL 이런식으로 직접 때려넣어줘도 되지만

사수님께서 api 노출 보안에 안좋으니 rewrite를 적용해보거라 하셨다

const nextConfig = {
  reactStrictMode: false,
  sassOptions: {
    includePaths: [path.join(__dirname, "styles")],
    prependData: `@import "@/scss/theme.scss";`,
  },
  async rewrites() {
    return [
      {
        source: "/APIURL/:path*",
        destination: `${process.env.NODE_API_URL}/:path*`,
      },
    ];
  },
};

그렇게 적용해본 rewirte

이렇게 적용하면 사용자가 개발자도구를 열어서 흠 얘네 api서버가 어디려나 ^^ 하고 염탐하려해도 못본다(보안이슈)

 

은근히 하다보면 코딩만 하면 끝나는게 아니라는걸 깨닫는다

최적화도 최적화인데 아무리 프론트단이라도 보안때문에 신경써야되는 부분들도 있고..

코딩만 하면 걍 재밌는데 네트워크는... 알면 알수록 머리아픈거같다 dns이슈터졌을때 멘탈 나갈뻔

 

728x90
Copyright © Nana
levup