nextjs 에서 request 객체를 통해 주소를 얻어오고 싶다면,
이 때는 x-forwarded-for
라는 헤더값을 사용하면된다.
사실 request.ip
나 request.geo
등 다양한 값들을 제공하지만, 특정환경에서만 채워지는 값들이라 undefined로 들어오는 경우가 많다.
request.geo
는 vercel 을 통해서 배포된 프로젝트에 대해서만 값이 생성된다.request.ip
는 클라이언트 환경의 설정에 따라 들어오지 않을수도 있따.x-forwarded-for
는 공식헤더값으로, cdn이나 프록시를 거치면서 추가되는 헤더값이다.
요청이 게이트(프록시나 cdn)를 하나 거칠떄마다 ':' 를 구분자로 ip주소가 하나씩 늘어난다. 따라서 최초 요청 클라이언트의 ip주소는 첫번째 요소가 된다.
다만 아무런 중간다리를 거치지않고 호출하는 경우, 해당 헤더값은 없을 수 있다.
그 경우 다른 방법을 생각해봐야 한다.
(다만 대부분 서비스는 cdn 을 두기때문에, x-forwarded-for
헤더값이 없는 경우는 흔치않을듯..)
접속한 클라이언트의 위치를 추적하기위해 geoip-lite
패키지를 사용하려했다.
모든 요청에 대해서 클라이언트의 지역을 체크하고싶었기에, 전역적인 레이어에 로직을 추가해야했다.
처음엔 모든 요청이 거쳐가는 middleware
레이어에서 체크하려했다. 하지만 아래 이슈를 마주했다.
browser.sentry-cdn.com_7.60.0_bundle.replay.min.js:8235 Uncaught Error: The edge runtime does not support Node.js 'path' module.
geoip-lite
는 node 런타임에서 동작하는 패키지다.
그러나 middleware 레이어는 서버사이드에서 동작하긴하지만, nodejs runtime
이 아닌 edge runtime
이라는 환경위에서 동작했다.
따라서 node 런타임의 패키지는 사용이 불가했다.
_app.tsx
레이어에서 수행하려하니
에러를 마주했다.
이유는 _app.tsx
는 서버사이드 뿐만아니라 클라이언트 사이드에서도 동작하는 컴포넌트이기 떄문이었다.
서버렌더링을 수행할때는 정상동작하더라도, 클라이언트 사이드에서 하이드레이션을 할 때 이슈가 발생했다.
비록 전역레이어는 아니지만 왜 동작을 하지 않는가에 대한 의문때문에 테스트해보았다.
이 page내의 node runtime 환경에서는 정상동작하고있었다.
하지만 모든 페이지에서 geoip-lite
를 사용해 위치를 확인하고 싶었기 때문에,
index.tsx
에서 체크한다는 말은 즉슨, 모든 page 하위의 index.tsx 마다 위치확인 로직을 중복으로 심어야 한다는 이야기었기에 포기했다.
결국에는 패키지가 아닌 ip기반의 위치를 확인해주는 http://ip-api.com/
라는 open api 서비스를 사용했다. 서비스가 다른 api에 의존한다는 사실이 영 내키진 않았지만, 위치를 체크해서 구현하고자 하는 기능이 핵심기능도 아니었기에 그냥 사용해보기로 했다.
노드 패키지를 nextjs 서버사이드에서 사용할때는 신중해야겠다.
특히 api endpoint가 아닌 page 에서 사용할 때는 더더욱 조심!
https://velog.io/@chacha_fe/Rendering-Edge-and-Node.js-Runtimes