2024.11.08

이짜젠·2024년 11월 8일
0

ip 주소 얻어오기

nextjs 에서 request 객체를 통해 주소를 얻어오고 싶다면,
이 때는 x-forwarded-for 라는 헤더값을 사용하면된다.

사실 request.iprequest.geo 등 다양한 값들을 제공하지만, 특정환경에서만 채워지는 값들이라 undefined로 들어오는 경우가 많다.

  • request.geo는 vercel 을 통해서 배포된 프로젝트에 대해서만 값이 생성된다.
  • request.ip는 클라이언트 환경의 설정에 따라 들어오지 않을수도 있따.

x-forwarded-for는 공식헤더값으로, cdn이나 프록시를 거치면서 추가되는 헤더값이다.

요청이 게이트(프록시나 cdn)를 하나 거칠떄마다 ':' 를 구분자로 ip주소가 하나씩 늘어난다. 따라서 최초 요청 클라이언트의 ip주소는 첫번째 요소가 된다.

다만 아무런 중간다리를 거치지않고 호출하는 경우, 해당 헤더값은 없을 수 있다.
그 경우 다른 방법을 생각해봐야 한다.
(다만 대부분 서비스는 cdn 을 두기때문에, x-forwarded-for 헤더값이 없는 경우는 흔치않을듯..)

nextjs의 runtime

접속한 클라이언트의 위치를 추적하기위해 geoip-lite 패키지를 사용하려했다.

모든 요청에 대해서 클라이언트의 지역을 체크하고싶었기에, 전역적인 레이어에 로직을 추가해야했다.

1. middleware

처음엔 모든 요청이 거쳐가는 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 런타임의 패키지는 사용이 불가했다.

2. _app.tsx

_app.tsx 레이어에서 수행하려하니

에러를 마주했다.

이유는 _app.tsx 는 서버사이드 뿐만아니라 클라이언트 사이드에서도 동작하는 컴포넌트이기 떄문이었다.
서버렌더링을 수행할때는 정상동작하더라도, 클라이언트 사이드에서 하이드레이션을 할 때 이슈가 발생했다.

page/index.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

profile
오늘 먹은 음식도 기억이 안납니다. 그래서 모든걸 기록합니다.

0개의 댓글