[React] Proxy Netlify 배포 후 Proxy가 안됐던 이유 (feat. 사설 IP와 내부 망)

Lemon·2022년 10월 31일
6

삽질

배포 자체가 안돼서 배포를 진행하는 것만 3일,
배포 후에 백엔드 API가 연결이 안돼서 해결하는 것만 2일이 걸렸다.
일주일 내내 해결해보려했지만, 결국 직원분들이 이유를 알려줘서 겨우 문제 해결을 할 수 있었다.


배포를 진행하는 것만 3일

문제 상황을 완전 잘 못 판단했다.

react npm start를 했을 때 실행되는 서버가 React Dev Server이고, CRA(create-react-app)가 서버를 제공해주는 것이다.
npm start를 하고 브라우저에게 localhost:3000 이라고 주소창에 쓰면 React Dev Server에 접속해서 html, js를 다운받아서 리액트 어플리케이션이 실행된다. 그러나 리액트 어플리케이션이 순수하게 리액트 어플리케이션 만으로 구동되는 경우는 별로 없고 ajax같은 기술을 이용해서 php나 장고가 서비스되고 있는 서버에 접속해서 데이터를 가져오거나 변경시키는 작업을 한다. 그때 사용하는 대표적인 api가 fetch이다.

수습 과제를 진행할 때 mock data와 백엔드api 두개를 사용했다.
mock data를 📂Public > 📂Data > 📃allGrout.json 로 만들어서 사용했다.

fetch('data/allGroup.json')

fetch 함수를 이용해서 path만 적어줄 경우, 자동으로 path 앞에 도메인 url이 붙는다.

백엔드 api를 연결할 경우 path만 적게되면 path 앞에 도메인인 localhost:3000이 붙기 때문에 데이터를 찾을 수 없다. (status code 404)

나는 이 문제를 해결하기 위해서 proxy를 사용했었다.

참고 링크🔗
https://junhyunny.github.io/information/react/react-proxy/

CRA(create-react-app)을 이용해서 리액트 어플리케이션을 만드는 경우 react-scripts을 사용하게 된다. react-scripts을 이용하면 package.json 파일에 proxy옵션을 추가해서 쉽게 프록시를 구축할 수 있다.

📃package.json

"proxy" : "https://localhost:8000"

package.json 위 내용을 입력하면 npm start 시 백엔드 api가 정상 동작한다. (status code 200)

배포 업데이트 문제

근데 문제는 배포 업데이트를 진행하면서 였다.
api 연결 전에 이미 github pages로 배포를 해둔 상태였고, proxy 업데이트 후에 push 를 진행했는데, 이전에 진행하던 것과 마찬가지로 당연히 업데이트가 되어있을 것이라고 생각했다. 😀

업데이트가 됐는데 왜 내용이 다르지?라고 혼자 생각하고 뻘짓을 엄청 했다. 이것 저것 고쳐보고 npm start했을 때의 결과물과 github pages의 결과물이 다른 것에 초점이 맞춰져서 이게 mock data와 백엔드 api를 같이 써서 생기는 오류라고 착각했다.
착각한 이유는 proxy 기본 개념 부족이 제일 컸다. proxy는 localhost:3000에 api_path가 있는지 확인하고 없다면 proxy로 설정된 api url에서 찾아서 3000번으로 보내주는 역할을 해주는 것인데, 나는 proxy를 설정하면 그게 기본 url로 설정되는 줄 알았다.
그래서 mock data와 백엔드 api가 다른 proxy를 바라보도록 해야겠다고 생각하고 proxy-middleware 설정하고 그랬는데 완벽한 뻘짓이었다.

왜 업데이트 상태를 체크하지 못했는가.

github pages의 업데이트 상태를 보통 push 하면 반영되었기 때문에 따로 확인할 생각을 못했던 것이 첫번째 이유이다. 이것 저것 다 해보다가 github pages의 결과물이 계속 동일한 것을 보고 설마 업데이트가 안되고있나…?라고 깨닫는게 생각보다 오래걸렸다ㅎ

깨닫고 나서는 github action의 용도에 대해 몰랐던게 두번째 이유이다. 업데이트를 어떻게 확인하는지 몰랐었다. github action에 들어가면 push 후에 build 되는 과정을 볼 수 있다. 이걸 아는 것도 꽤 오래 걸렸던것 같다…

결론은 결국 proxy 설정 후에 build가 되지않고 있었다는것이다.

진짜 해결해야할 첫번째 문제는 배포부터 하는 것이었다.

https://velog.io/@remon/React-Github-Pages-build-실패
https://velog.io/@remon/React-Netlify로-배포하기
위 링크를 타고 가면 배포하는 과정이 적혀있다.


배포 후 백엔드 API가 연결이 안돼서 해결하는 것만 2일

해결 과정

배포 후 Proxy 로 설정해둔 api가 status code 400이 나왔다.

porxy 설정이 먹히지 않았던 이유

배포 전에 설정했던 proxy는 CRA(create-react-app)로 만든 react-scripts을 이용해서 프록시를 구축한 것이다. CRA 가 만들어준 React Dev Server에서 test로 보기 위한 설정인 것이었다.
그렇다면 test가 아니라 실제 배포 할 경우에 proxy는 어떻게 설정해줘야할까?

Netlify 배포시 proxy 셋팅하는 방법

https://velog.io/@mochapoke/TIL-netlify로-배포시-proxy-셋팅하는-방법
위 링크를 참고해서 설정해줬다.

  1. api 사용 파일에서 아래와 같이 작성
const PROXY = window.location.hostname === 'localhost' ? '' : '/proxy';
const URL = `${PROXY}/data/allGroup.json`;

await = axios.get(URL, {
    // ...
})
  • 로컬 서버의 경우 package.json에서 설정한 proxy로 api가 연동되고, 그 외에는 api 주소 앞에 proxy가 붙는다.
  1. 최상위 경로에 netlify.toml 생성 후 아래와 같이 작성한다.
[[redirects]]
  from = "/proxy/*"
  to = "https://api url/:splat"
  status = 200
  force = true
  • package.json과 같은 위치
  • :spliat까지 써주기

위의 설정을 마치고 나니 status code 가 500으로 바뀌었다.

여기서부터 멘붕이 시작되었다.
왜 500 코드가 나올까… 서버 에러 응답 코드는 요청을 처리하는 과정에서 서버가 문제가 생겼다는 것이다.
나는 계속 proxy 문제인 줄 알고, 한참을 관련된것만 찾아봤다.

https://velog.io/@ezae/React-build배포-후-api-response-문제
https://stackoverflow.com/questions/48291950/proxy-not-working-for-react-and-node
https://velog.io/@familyman80/node-module-삭제방법
https://velog.io/@hinyc/배포-Netlify-proxy-설정-9gmuvrr8
https://velog.io/@leejin/TIL220519
https://docs.netlify.com/routing/headers/#basic-authentication-headers

위 링크들을 몇번씩 정독하고 시도해봤는지 모른다.. 근데 결론은 해도 안됐다는 것..ㅋㅋㅋㅋㅋ
내가 전혀 다른 방향으로 접근하고 있었던 것이다.

500이 나온 이유!!

회사에서 사용하는 api는 사설 IP를 사용하기 때문에 내부망을 통해서만 접근이 가능하다.
proxy는 api path를 proxy가 설정된 곳으로 전달해주는 역할을 해주는데, proxy로 전달 해주는 전달 서버가 Netlify 서버이다.

(배포한 페이지에서 개발자도구 네트워크 탭을 통해 api를 확인해보면 server가 Netlify로 되어있다. )

Netlify 서버는 외부 망을 사용하는 외부 서버이다. proxy로 적어준 url은 내부망에 있는 사설 IP에 접근하는 url이다. 외부 망에서 내부 망으로 접근은 불가능하다. 즉, Netlify가 proxy URL에 접근할 수 없다는 소리이다. 이 때문에 500이 나온것이다.

const PROXY = window.location.hostname === 'localhost' ? '' : '/proxy';
const URL = `${PROXY}/data/allGroup.json`;

await = axios.get(URL, {
    // ...
})

proxy로 접근할 수 없다면 현재 URL은 PROXY/data/allGroup.json 으로 path만 적혀있는 상황이다.

외부 서버에서 주소를 보고 찾아오려면 전체 주소가 필요하다.

  • 택배 배달을 예시로 볼 때, 00시 00동 00아파트, 101동 501호 라는 주소를 보면 정확히 찾아가겠지만, 101동 501호 만 보고는 어느 지역 어느 아파트인지 파악하지 못해서 못 찾아가는 것과 동일하다.
  • 그렇다면 npm start는 101동 501호만 보고 어떻게 찾았을까?
    • 내부망에서 작업한 로컬 페이지(localhost)이기 때문에 가능하다.
      • 이미 아파트 단지 안에 들어와있다고 생각하면 된다.

내부망(wi-fi) = 나라
IP(도메인) = 주소
path = 상세 주소

  • 이미 아파트 단지 안에 들어와 있는 경우 상세 주소만 필요
  • 같은 나라에만 있는 경우 주소 + 상세주소 전체 필요

회사에서 사용하는 wi-fi는 동일하다. 배포한 페이지를 들어갈 때 동일한 회사 wi-fi로 들어간다면 api URL에 들어갈 수 있다. 그렇기 때문에 proxy를 설정하는게 아니라 fetch안에 api_path가 아닌 api URL의 전체 주소를 적어주면 되는것이다.

fetch('api URL')

이렇게 하니 데이터를 받아올 수 있었다.

+ 추가

애초에 Proxy에 대한 개념이 부족했던 것이었다.
Proxy는 CRA로 React Dev Server(개발용 서버)를 사용할 때 생기는 오류를 해결해주기 위해서 사용하는 React Dev Server 테스트용 설정이다. 그러니 실서버의 경우 React Dev Server를 쓰지 않고 PHP나 장고가 제공하는 서버를 쓰거나, PHP나 장고도 마찬가지로 아파치 같은 웹 서버를 쓰기 때문에 결국에는 리액트와 백엔드 서버가 같은 주소에 같은 포트에서 서비스 될 것이다. 그렇기 때문에 실서버에서는 Proxy 설정 자체가 필요없다.

그런데도 400 에러에서 500 에러로 바뀐 이유는, localhost 주소가 아니면 proxy 주소로 api를 연결해달라고 설정해뒀기 때문인데, 그 이유가 외부망을 이용하는 웹 호스팅 사이트를 사용했을 경우 내부에 있는 api주소로 접근해야되는데, 외부에서는 접근을 못하기 때문에 proxy로 설정한 주소가 읽히지 못하고 path주소만 읽혀서 500에러가 나왔던 것이다.


삽질 한 이유

  • 네트워크 기본 지식 부족
    • 사설 IP, 내부망, 외부망
    • 배포 환경에 대한 이해
  • PROXY 기본 개념 이해 부족
  • REACT npm start 동작 원리 이해 부족

배운 것

  • proxy 기본 개념 학습
  • github action 사용하는 법
  • Netlify 배포하는 법
  • react npm start 동작 원리 학습
  • 네트워크 기본 지식 학습
    • 사설 IP에 대하여
    • 내부망과 외부망에 대하여
    • 배포 환경에 대하여

npm start도 그냥 썼고, proxy도 그냥 쓰라니까 썼었다..ㅋㅋㅋ
사설 IP와 내부망, 외부망에 대한 이해도 아예 없었다ㅠㅠ
애초에 이런 기본 지식들이 부족하니까 문제 상황이 생겨도 정확한 원인을 파악할 수 없어서 간단한 문제를 어렵게 삽질하면서 끌고가게 되었다. 결국 해결해놓고 보면 정말 별 거 아니었는데 말이다ㅠㅠ 이번 삽질을 하면서 얻은게 정말 많다!! 재밌는 일주일이었다!🔥

profile
프론트엔드 개발자 가보자고~!!

1개의 댓글

comment-user-thumbnail
2024년 1월 25일

마지막 네트워크 지식 도움 많이되었습니다

답글 달기