[Next.js] env와 next.config.js를 활용하여 API key 숨기기 - (5)

환경 변수란? (Envrionment Variables)

환경 변수란 프로그램 외적으로 설정되는 변수로써, 주로 API Key와 같은 서비스 관련 정보들을 변수화하여 저장하고 불러올 때 사용된다. 환경 변수를 활용함으로써 개발자는 코드 내에 명시하고 싶지 않은 정보를 따로 분리하고 관리할 수 있게 된다.

Next.js에서의 환경 변수 사용 예시

API Key를 사용한 통신을 통해 인기 영화 목록을 불러오는 코드가 있다고 가정해 보자.

useEffect(() => {
  const popular = async () => {
    const response = await fetch(
      `https://api.themoviedb.org/3/movie/popular?api_key='사용자의_API_Key'`
    );
    return response.json();
  };
  popular().then((res) => setMovies(res));
}, []);

예시는 useEffect를 통한 ‘TMDB’라는 사이트의 API로부터 인기 영화 목록을 요청하는 통신을 담고 있다. 이 경우, 코드 상에 사용자의 API 키가 노출될 뿐만 아니라, 개발자 도구의 Network 탭에서도 호출과 응답이 이루어지는 주소에 키가 노출이 되어 있다. 만약 이 키가 유료로 배포되는 키거나, 이 키를 통해 서버를 조작할 수 있다면 보안 상 굉장히 위험한 상황이므로 이를 숨겨줘야 한다.

// .env.local
API_KEY=사용자의_API_KEY

최상위 디렉토리에 .env.local 파일을 만들어 주고, 여기에 숨기고자 하는 정보를 적어주면 된다. 사용할 수 있는 .env 파일의 종류는 .env.development, .env.production, .env 등 다양하지만 공식 문서에 따르면 대부분의 경우 .env.local로 충분하다고 되어있으므로 상황에 따라 사용하면 된다.

이후 next.config.js를 수정해주면 된다.

// next.config.js
const API_KEY = process.env.API_KEY;

const nextConfig = {
  reactStrictMode: true,
  async rewrites() {
    return [
      {
        source: "/api/movies",
        destination: `https://api.themoviedb.org/3/movie/popular?api_key=${API_KEY}`,
      },
    ];
  },
};

module.exports = nextConfig;
const API_KEY = process.env.API_KEY;

.env.local에 있는 환경 변수에 접근하기 위해선 process.env.변수이름으로 접근하면 된다.

async rewrites() {
    return [
      {
        source: "/api/movies",
        destination: `https://api.themoviedb.org/3/movie/popular?api_key=${API_KEY}`,
      },
    ];
  },

이 부분을 이해하기 위해선 rewrites()를 이해해야 한다. rewrites()는 브라우저가 source에 있는 경로로 접근하면 destination에 해당하는 경로로 리다이렉션을 해주는 역할을 한다. 하지만 이 때 URL 자체는 변하지 않으면서 리다이렉션을 해준다.
유사한 기능으로는 redirects()가 있는데, 이 메서드는 URL도 함께 변하면서 리다이렉션이 이루어진다. 여기에서 rewrites()를 사용한 이유는 redirects()를 사용할 경우 URL의 변화가 브라우저에도 나타나서 통신 과정에서 사용되는 API_KEY가 드러나기 때문이다.

이제 다시 useEffect 부분으로 돌아가서 통신할 URL을 수정해주면 된다.

useEffect(() => {
  const popular = async () => {
    const response = await fetch("/api/movies");
    return response.json();
  };
  popular().then((res) => setMovies(res));
}, []);

이렇게 수정해줌으로써 fetch를 시도할 때 리다이렉션이 된 상태로 진행되기 때문에 정상적으로 통신이 이루어진다. 또한 API 키가 숨겨졌기 때문에 보안성도 향상되었다.

참고: Next.js 공식문서

Categories:

Published: