CORS 에러를 해결하는 방법

MODAC·2023년 2월 6일
0

01. What CORS?


CORS는 Cross-Origin Resource Sharing의 줄임말로 직역하면 "교차 출처 리소스 공유 정책"으로 해석할 수 있습니다. 개발자들에게 한번 쯤 찾아오는 에러로 악명높은 CORS는 왜 나타날까요?

브라우저는 HTTP 요청을 받을 때 어떤 요청인지에 대해 각각 다른 특징을 가지고 있습니다.

Cross-Origin 정책

<link> 태그의 href 에서 다른 사이트의 .css 리소스에 접근하거나, <img> 태그의 src 에서 다른 사이트의 .png, .jpg 등의 리소스에 접근하거나, <script> 태그의 src 에서 다른 사이트의 .js 리소스에 접근하는 것이 가능합니다.
(type="module" 속성은 제외)


XMLHttpRequest, Fetch API

Same-Origin 정책

다른 도메인에게 ajax 요청 API 호출 시, 웹 폰트 CSS 파일 내 @font-face에서 다른 도메인의 폰트 사용 시, 자바스크립트에서의 요청은 기본적으로 서로 다른 도메인에 대한 요청을 보안 상 제한, 브라우저는 기본으로 하나의 서버 연결만 허용되도록 설정되어 있습니다.

출처

Same-Origin 정책

웹 콘텐츠의 출처(origin)는 접근할 때 사용하는 URL의 스킴(프로토콜), 호스트(도메인), 포트로 정의됩니다. 두 객체의 스킴, 호스트, 포트가 모두 일치하는 경우 같은 출처를 가졌다고 말합니다.
일부 작업은 동일 출처 콘텐츠로 제한되나, CORS를 통해 제한을 해제할 수 있습니다.

일반적인 CORS 해결법

프론트엔드가 개발한 React 앱에서 브라우저 쪽으로 요청을 보냅니다. 그러면 브라우저는 백엔드, 즉 서버 쪽으로 리소스를 요청하게 됩니다. 이때 접근 권한이 있는지, 즉 출처가 같은지 확인하는데 이때 백엔드 서버는 정상적으로 200 OK 응답을 브라우저에게 보냅니다. 마지막으로 브라우저는 받은 리소스 및 응답과 함께 출처가 같은지 아닌지 확인하게 되는데, 이때 출처가 다르다면 응답을 파기(CORS Error) 하고, 출처가 같다면 응답을 파기하지 않고 다시 프론트엔드 쪽으로 응답을 보내주는 것입니다.

02. Proxy


위의 그림은 proxy를 적용해 브라우저를 속인 후 흐름입니다. React 앱에서 브라우저를 통해 API를 요청할 때, proxy를 통해 백엔드 서버로 요청을 우회하여 보내게 됩니다. 그러면 백엔드 서버는 응답을 React 앱으로 보내고, React 앱은 받은 응답을 백엔드 서버 대신 브라우저에게 전달합니다. 이렇게 되면 출처가 같아지기 때문에 브라우저는 이 사실을 눈치 채지 못하고 허용하게 됩니다.

webpack dev server proxy

webpack dev server에서 제공하는 proxy 기능을 사용하는 방법

CRA 를 통해 만든 리액트 프로젝트에서는 package.json 에서 "proxy" 값을 설정하여 쉽게 적용할 수 있도록 구성이 되어 있습니다.

...
"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 주소"
}

기존의 fetch, 혹은 axios를 통해 요청하던 부분에서 도메인 부분을 제거합니다.

export async function getAllfetch() {

    const response = await fetch('우회할 api주소/params');
    .then(() => {
			...
		})
}

export async function getAllfetch() {

    const response = await fetch('/params');
    .then(() => {
			...
		})
}

React Proxy

React Proxy 사용법

수동으로 proxy를 적용해줘야 하는 경우가 있는데, 이때는 http-proxy-middleware 라이브러리를 사용해야 합니다.

01. 설치

npm install http-proxy-middleware --save

02. React App의 src 파일 안에서 setupProxy.js 파일 작성

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

module.exports = function(app) {
  app.use(
    '/api', //proxy가 필요한 path prameter를 입력합니다.
    createProxyMiddleware({
      target: 'http://localhost:5000', //타겟이 되는 api url를 입력합니다.
      changeOrigin: true, //대상 서버 구성에 따라 호스트 헤더가 변경되도록 설정하는 부분입니다.
    })
  );
};

03. 기존의 fetch, 혹은 axios를 통해 요청하던 부분에서 도메인 부분을 제거

export async function getAllfetch() {

    const response = await fetch('우회할 api주소/params');
    .then(() => {
			...
		})
}

export async function getAllfetch() {

    const response = await fetch('/params');
    .then(() => {
			...
		})
}

0개의 댓글