React + Express | CORS 설정하기

Noma·2021년 8월 24일
5

CORS개념은 이전 포스팅에서 다뤘으므로 생략하겠습니다.

프론트는 http://localhost:3000, 서버는 http://localhost:8000이라고 가정할 때, 프론트에서 axios.get('http://localhost:8000')하게 되면 서로 다른 origin으로 인해 콘솔에 CORS 이슈가 생긴다.

Access to XMLHttpRequest at 'http://localhost:8000' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

이 경우 서버쪽에서 cors 설정을 헤더에 실어 보내주는 방법이 정석적인 방법이지만, 제 3자가 다른 웹사이트의 데이터를 가져오는 경우라면 쉽지 않다. 따라서 프론트측에서 CORS를 설정하는 방법에 대해서도 다뤄보려고 한다.

1. Front 측에서 CORS 설정하기

1.1 package.json에서 proxy 설정하기

웹팩 개발서버의 프록시를 사용하게 되면, 브라우저 API를 요청할 때 백엔드 서버에 직접적으로 요청을 하지 않고, 현재 개발서버의 주소로 요청을 하게 된다. 그러면 웹팩 개발 서버에서 해당 요청을 받아 그대로 백엔드 서버로 전달하고, 백엔드 서버에서 응답한 내용을 다시 브라우저쪽으로 반환한다.

웹팩 개발서버의 proxy 설정은 원래 웹팩 설정을 통해서 적용을 하지만, CRA를 통해 만든 리액트 프로젝트에서는 package.json 에서 "proxy" 값을 설정하여 쉽게 적용 할 수 있다.

다음과 같이 package.json 파일에 "proxy":"허용할 주소"를 추가해주자.

   },
   "proxy":"http://localhost:8000" //접속하려는 서버의 루트 URL
}

그러면 실제 HTTP request를 전송하는 코드에서는 위에서 선언한 루트 URL을 제외한 나머지 뒷부분을 주소로 하여 요청하면 된다.
axios.get('http://localhost:8000/api/user');=>axios.get('/api/user');

1.2 http-proxy-middleware 사용하기

다음으로 http-proxy-middleware라는 라이브러리를 사용해 프록시 서버를 만들어주는 방법이 있다.

  1. http-proxy-middleware 설치하기
$ yarn add http-proxy-middleware
  1. src폴더 안에 setupProxy.js 파일 생성 후 아래와 같이 설정하기
const { createProxyMiddleware } = require('http-proxy-middleware');

module.exports = function(app) {
    app.use(
        createProxyMiddleware('/api', {
            target: 'http://localhost:8000', //접속하려는 서버의 루트 URL
            changeOrigin: true
        })
    );
};

이렇게 하면 로컬 환경에서 /api로 시작하는 URL로 보내는 요청에 대해 브라우저는 http://llocalhost:3000/api로 요청을 보낸 것으로 알고 있지만, 사실 뒤에서 웹팩이 http://localhost:8000으로 요청을 프록싱해주기 때문에 마치 CORS 정책을 지킨 것처럼 브라우저를 속일 수 있다. 즉, 프록싱을 통해 CORS 정책을 우회할 수 있게 된다.

따라서 axios.get('/api/user')와 같이 /api로 시작하는 주소로 요청을 보내면, 브라우저를 속여 axios.get('http://localhost:8000/api/user')로 요청을 보내게 된다.

참고 : setupProxy.js는 개발 서버를 시작할 때 자동으로 등록되므로, 따로 import해줄 필요 없다.

하지만 이 방법은 실제 프로덕션 환경에서도 클라이언트 어플리케이션의 소스를 서빙하는 출처와 API 서버의 출처가 같은 경우에 사용하는 것이 좋다.

2. Server 측에서 CORS 설정하기

다음으로 CORS를 express 서버측에서 허용해주는 방법을 알아보겠다.

2.1 Access-Controll-Allow-Origin 응답 헤더 추가

app.use((req, res) => {
    res.header("Access-Control-Allow-Origin", "*"); // 모든 도메인 허용
    res.header("Access-Control-Allow-Origin", "http://localhost:3000"); // 특정 도메인 허용
});

*는 모든 출처에서 오는 요청들을 다 받겠다는 의미이므로 보안상 좋지 않다. 따라서 두 번째 줄처럼 허용할 특정 주소를 지정해주도록 하자.

2.2 CORS 미들웨어 사용하기(👍)

마지막으로 cors 미들웨어를 사용하는 방법이다. 개인적으로 가장 쉽고 어떠한 예외(프론트에서의 proxy 설정이 배포 후엔 적용이 안되는 문제를 겪었었음)없이 잘 작동하는 것 같아 이 방법으로 CORS를 설정하기를 추천한다.

  1. cors 설치하기
$ npm i cors
  1. express 앱에 적용하기
import express from "express";
import cors from 'cors';

const app = express();
app.use(cors()); //모든 접근 허용 

모든 접근을 허용하지 말고 아래처럼 특정 도메인을 적어주자.

app.use(cors({ origin: 'http://localhost:3000'}));

➕ origin에 배열을 사용하면, 프론트단의 로컬 주소, 배포 주소가 모두 서버에 접근 가능하도록 해줄 수 있다.

app.use(cors({ origin: [
  'http://localhost:3000',
  'https://nomalog.netlify.app'
]));

참고 자료

profile
Frontend Web/App Engineer

1개의 댓글

comment-user-thumbnail
2022년 3월 25일

감사합니다!

답글 달기