
키워드를 검색해서 해당 음식점을 찾는 이 기능은 카카오 API를 활용해서 구현을 했다. 그러나 이 과정에서 활용되는 API KEY 값이 노출되는 것을 발견했다.
먼저 문제가 발생했던 방식은 카카오 API와 클라이언트가 직접 통신을 했다. 사진을 보면 Authorization에 API KEY를 화면에서 쉽게 볼 수 있었다.

API KEY를 깃허브에 올리지 않기 위해서 env 파일에 환경변수 설정을 해주었다. 그로인해 깃허브에는 올라가지 않았기 때문에 API KEY가 노출될 거라는 건 생각을 하지 못 했다. 그러나 이건 잘못된 생각이었다. 아무리 env 파일에 API KEY를 환경변수 설정을 해주었다고 해도 클라이언트에서 API KEY를 가지고 직접 카카오 API와 통신할 때 쓰는 것이기 때문에 노출을 피할 수는 없는 것이었다.
일단 문제가 됐던 원인이 클라이언트가 API KEY를 가지고 카카오 API와 직접 통신했던 것이라고 생각했다.
그래서 생각한 해결 방법은 서버가 중계자 역할을 할 수 있도록 하는 것이다. 즉, 클라이언트와 카카오 API 중간에 서버가 껴서 카카오 API와 직접 통신하는 것은 서버가 되는 것이다. 그러면 API KEY를 클라이언트에서는 사용할 일이 없고 서버에서 사용하기 때문에 노출이 되는 것을 막으면서 보안적으로도 안전한 방법이라고 생각했다.
로직 순서는 다음과 같다.
이 순서로 구현하면 API KEY는 노출되지 않고 오류없이 화면에 데이터가 잘 보인다.
먼저 원하는 데이터를 요청하기 위해서 카카오 API에서 정한 방식으로 데이터를 담아서 보내줘야 한다.
const url = `https://dapi.kakao.com/v2/local/search/keyword?query=${keyword}&page=${currentPage}&size=${pageSize}&x=${currentLng}&y=${currentLat}&radius=${10000}`;
클라이언트에서는 이런 식으로 쿼리 파라미터를 사용해서 데이터를 전송했었다. 이걸 서버에서 똑같이 해야 하는데 저 데이터를 담은 변수들이 클라이언트에 있기 때문에 서버로 보내줘야 했다.

URLSearchParams를 사용해서 필요한 데이터들을 담아주었다. 여기서 중요한 점은 서버에 요청을 보낼 완전한 URL 문자열을 만들기 위해서는 URLSearchParams 객체를 직접적으로 URL에 붙일 수 없다. 그래서 URLSearchParams.toString() 메소드를 사용해 객체를 쿼리 문자열 형태로 변환해야 한다.
결론적으로, .toString() 메소드는 URLSearchParams 객체를 HTTP 요청에 적합한 쿼리 스트링 형태로 변환하여, 실제 HTTP 요청의 URL 일부로 사용할 수 있게 만들어준다.
그래서 타입이 numbers인 것들을 .toString() 메소드를 사용해 문자열로 변환해 주었다.

클라이언트에서 URLSearchParams로 필요한 데이터들을 담아서 서버에 요청했다. 그리고 위 코드처럼 서버에서는 req.nextUrl.searchParams.get()로 접근해서 클라이언트에서 설정한 키 변수를 그대로 작성해서 값을 가져온다. 그리고

이제 그다음은 위 코드 보면 원래 클라이언트에서 요청했던 방식이랑 똑같이 하면 된다. 마지막에 data를 return 해주는 것이 중요하다.
이렇게 구현한 결과 API KEY가 노출되는 문제가 해결됐다 !!!