MERN에서 CORS 오류를 해결하는 방법 (안전한 방법)
Source: Dev.to
왜 이런 일이 발생하나요?
버그가 아니라 기능입니다.
브라우저에는 동일 출처 정책(Same‑Origin Policy) 이라는 내장 보안 메커니즘이 있습니다. 이 정책의 역할은 한 웹페이지의 악성 스크립트가 다른 웹페이지의 민감한 데이터에 접근하는 것을 방지하는 것입니다.
일반적인 로컬 MERN 스택 설정에서는:
- React 프론트엔드가
http://localhost:3000에서 실행되고 - Node/Express 백엔드가
http://localhost:5000에서 실행됩니다.
브라우저 입장에서는 서로 다른 포트가 완전히 별개의 출처(origin) 로 인식됩니다. 브라우저는 두 서버가 같은 사람에 의해 운영된다는 사실을 알지 못하고, 낯선 사람이 서버와 통신하려는 시도로 판단해 요청을 차단합니다.
해결책: 프론트엔드 화이트리스트에 추가하기
이를 해결하려면 Express 서버에 “괜찮아. 포트 3000에 있는 프론트엔드가 내 것이야.” 라고 알려줘야 합니다.
이를 위해 Cross‑Origin Resource Sharing (CORS) 헤더를 사용합니다. Node.js에서 가장 간편하게 관리하는 방법은 cors 미들웨어 패키지를 이용하는 것입니다.
1단계: 패키지 설치
터미널에서 백엔드(서버) 폴더로 이동한 뒤 다음 명령을 실행합니다:
npm install cors
2단계: 서버 설정
메인 서버 파일(보통 index.js 혹은 server.js)을 열고, 라우트를 정의하기 앞에 cors를 import하고 사용합니다.
코드 예시:
const express = require('express');
const cors = require('cors');
const app = express();
// 마법의 라인 👇
app.use(cors({
origin: 'http://localhost:3000', // 프론트엔드만 화이트리스트에 추가
credentials: true // 쿠키/세션을 사용할 경우 필요
}));
app.use(express.json());
// 여기서 라우트를 정의합니다...
// app.use('/api/users', userRoutes);
app.listen(5000, () => {
console.log('Server running on port 5000');
});
origin을 http://localhost:3000 으로 지정하면 서버가 브라우저에 올바른 헤더를 반환하고, 브라우저는 데이터를 허용하게 됩니다.
⚠️ 중요한 프로덕션 경고
밤늦게 디버깅하다 보면 StackOverflow 답변 중에 다음과 같이 쓰라고 하는 경우가 있습니다:
// 위험 구역
app.use(cors());
이 코드는 오류를 해결하지만, 인터넷에 존재하는 모든 웹사이트가 내 API에 요청을 보낼 수 있게 허용합니다. 로컬 테스트에서는 괜찮을 수 있지만, 프로덕션에 절대 배포하면 안 됩니다. 심각한 보안 구멍을 만들게 됩니다.
프로덕션 환경에서는 프론트엔드 URL을 환경 변수로 관리해 보안을 유지하세요:
app.use(cors({
origin: process.env.FRONTEND_URL, // 예: 'https://myapp.com'
}));
요약
- CORS는 프론트엔드와 백엔드가 서로 다른 포트/도메인에 있을 때 발생합니다.
- 백엔드에
cors를 설치하고, 특정 프론트엔드 출처를 화이트리스트에 추가하도록 설정하면 해결됩니다. - 프로덕션에서는 절대
app.use(cors())와 같이 모든 출처를 허용하는 설정을 사용하지 말고, 허용할 출처를 명시적으로 제한하세요.