데굴데굴

<React> React에서 Proxy로 CORS 에러 다루기 본문

Programming/React

<React> React에서 Proxy로 CORS 에러 다루기

aemaaeng 2022. 12. 8. 21:43

Proxy

CORS 처리를 백엔드 개발자에게 요청할 필요 없이 리액트 라이브러리나 webpack dev server에서 제공하는 proxy 기능을 이용하면 CORS 정책을 우회할 수 있다.

브라우저를 속인다고 생각하면 된다.

1. webpack dev server의 proxy 기능 이용

클라이언트 폴더 package.json의 맨 밑에 프록시 설정을 추가한다.
아무데나 넣어도 상관은 없지만 보통 알아보기 쉽게 맨 밑에 추가한다고 한다.

...
"browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
    "proxy" : "우회할 API 주소"
}

예를 들어, 리액트 앱이 열린 주소가 http://localhost:3000이고, 데이터를 받아올 서버의 주소는 http://localhost:4000이라면 "proxy" 키의 값으로 서버의 주소인 "http://localhost:4000"을 넣으면 된다.

 

그리고 이렇게 작성되어있던 fetch 함수를

export const getAllBooks = async () => {
    const response = await fetch("http://localhost:4000/api/books");
    return await response.json();
};

 

도메인 주소를 지우고 파라미터만 남겨둔다.

export const getAllBooks = async () => {
    const response = await fetch("/api/books");
    return await response.json();
};

3000번 포트로 요청을 보내고 있다.

이렇게 도메인을 지우면 요청을 보낼 때 현재 페이지의 도메인으로 인식하게 되어http://localhost:3000/api/books로 요청이 보내진다.
이러면 webpack dev server에서 이 요청을 백엔드 서버로 전달하고, 백엔드 서버는 응답 내용을 브라우저로 반환한다.

 

수정할 때마다 꼭 서버랑 앱 껐다 켜기!
-> 오늘 정말 많은 오류를 만났는데 대부분 이걸로 해결되었다....... 하하 퍼니

 

보통 웹사이트를 만들 때 여러 개의 도메인에서 다양한 요청을 받아오는 경우가 더 많을 것이다.
그럴 땐 package.json에서 "proxy" 키에 우회할 api 주소를 배열 형태로 집어넣는 방법이 있다.
하지만 이렇게 전역으로 여러 개 설정하는 방법은 CRA(create-react-app)로 만든 프로젝트에서는 유효하지 않다.
따라서 리액트 라이브러리 http-proxy-middleware를 불러와 처리해야 한다.
사용법은 라이브러리 깃헙 리드미에 잘 설명되어 있다.

 

GitHub - chimurai/http-proxy-middleware: The one-liner node.js http-proxy middleware for connect, express, next.js and more

:zap: The one-liner node.js http-proxy middleware for connect, express, next.js and more - GitHub - chimurai/http-proxy-middleware: The one-liner node.js http-proxy middleware for connect, express,...

github.com

2. http-proxy-middleware 라이브러리

클라이언트 폴더에서 아래 명령어로 라이브러리를 설치한다.

npm install http-proxy-middleware --save

src 폴더 안에 setupProxy.js를 만들어 라이브러리를 불러와 아래처럼 작성한다.

const { createProxyMiddleware } = require('http-proxy-middleware');

module.exports = function(app) {
  app.use(
    '/api', //proxy가 필요한 path parameter
    createProxyMiddleware({
      target: 'http://localhost:4000', //타겟이 되는 api url
      changeOrigin: true, // 서버 구성에 따른 호스트 헤더 변경 여부 설정
    })
  );
};

파일명은 다른걸로 하면 안되고 setupProxy.js로 해야한다.

받아올 서버가 여러 개일 때에는 두 가지 방법으로 작성해줄 수 있다.


http://localhost:4000/apihttp://localhost:5000/api2 를 처리해야 한다고 가정하자.

1. 여러 개의 app.use()로 각각 처리하기

const { createProxyMiddleware } = require('http-proxy-middleware');

module.exports = function(app) {
  app.use(
    '/api', //proxy가 필요한 path parameter
    createProxyMiddleware({
      target: 'http://localhost:4000', //타겟이 되는 api url
      changeOrigin: true, // 서버 구성에 따른 호스트 헤더 변경 여부 설정
    })
  );
    app.use(
    '/api2', 
    createProxyMiddleware({
      target: 'http://localhost:5000',
      changeOrigin: true,
    })
  );
};

2. 라우터 이용하기

const { createProxyMiddleware } = require('http-proxy-middleware');

module.exports = function(app) {
  app.use(
    createProxyMiddleware(
      ['/api', '/api2'],
      {
        target: "http://localhost:4000",
        changeOrigin: true,
        router: {
          "/api2": "http://localhost:5000"
        }
      }
    )
  );
};

각 엔드포인트를 배열로 넣은 다음 두 번째 엔드포인트부터는 router로 분기해준다.

 

참고

 

GitHub - chimurai/http-proxy-middleware: The one-liner node.js http-proxy middleware for connect, express, next.js and more

:zap: The one-liner node.js http-proxy middleware for connect, express, next.js and more - GitHub - chimurai/http-proxy-middleware: The one-liner node.js http-proxy middleware for connect, express,...

github.com

 

CORS는 왜 이렇게 우리를 힘들게 하는걸까?

이번 포스팅에서는 웹 개발자라면 한번쯤은 얻어맞아 봤을 법한 정책에 대한 이야기를 해보려고 한다. 사실 웹 개발을 하다보면 CORS 정책 위반으로 인해 에러가 발생하는 상황은 굉장히 흔해서

evan-moon.github.io

 

9. CORS 와 Webpack DevServer Proxy · GitBook

9. CORS 와 Webpack DevServer Proxy 브라우저에서 기본적으로 API를 요청 할 때에는 브라우저의 현재 주소와 API 의 주소의 도메인이 일치해야만 데이터를 접근 할 수 있게 되어 있습니다. 만약 다른 도메

react.vlpt.us

 

Comments