현대의 웹 애플리케이션은 단일 서버에서 모든 것을 처리하지 않습니다. 프론트엔드는 A 도메인에, API 서버는 B 도메인에 있는 경우가 허다하죠. 이때 브라우저 콘솔창에 나타나는 “Access-Control-Allow-Origin” 관련 에러는 우리를 당혹스럽게 합니다. 이것이 바로 CORS(Cross-Origin Resource Sharing) 정책 때문입니다.
목차
-
CORS(교차 출처 리소스 공유)의 정의
-
CORS가 작동하는 방식 (3가지 시나리오)
-
핵심 헤더(Header) 살펴보기
-
CORS 에러를 해결하는 올바른 방법
-
요약 및 결론
1. CORS(교차 출처 리소스 공유)의 정의
**CORS(Cross-Origin Resource Sharing)**는 추가 HTTP 헤더를 사용하여, 한 출처(Origin)에서 실행 중인 웹 애플리케이션이 다른 출처의 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제입니다.
-
배경: 브라우저는 기본적으로 보안을 위해 **SOP(동일 출처 정책)**를 따릅니다. 하지만 다른 출처의 리소스가 필요한 상황이 많아지면서, 안전하게 예외를 허용하기 위해 CORS가 만들어졌습니다.
-
핵심: CORS는 ‘에러’ 그 자체가 아니라, 안전한 공유를 위한 **’교환 규약’**입니다.
2. CORS가 작동하는 방식 (3가지 시나리오)
브라우저는 요청의 성격에 따라 세 가지 방식으로 CORS를 확인합니다.
① 예비 요청 (Preflight Request)
가장 흔한 방식입니다. 실제 요청을 보내기 전, OPTIONS 메서드를 통해 서버가 해당 요청을 허용하는지 미리 확인합니다.
-
특징: 브라우저가 스스로 판단하여 먼저 “이거 보내도 돼?”라고 물어보는 단계입니다.
② 단순 요청 (Simple Request)
일부 조건(GET, POST, HEAD 메서드 등)을 만족하면 예비 요청 없이 바로 본 요청을 보냅니다. 하지만 조건이 까다로워 현대의 REST API에서는 자주 쓰이지 않습니다.
③ 인증된 요청 (Credentialed Request)
쿠키나 인증 헤더를 포함한 요청입니다. 이 경우 보안이 더 강화되어, 서버 설정 시 Access-Control-Allow-Origin에 와일드카드(*)를 사용할 수 없습니다.
3. 핵심 헤더(Header) 살펴보기
CORS를 제어하기 위해 서버가 응답에 포함해야 하는 주요 헤더들입니다.
-
Access-Control-Allow-Origin: 어떤 출처의 접근을 허용할 것인가? (가장 중요) -
Access-Control-Allow-Methods: 어떤 HTTP 메서드(GET, POST, PUT 등)를 허용할 것인가? -
Access-Control-Allow-Headers: 어떤 커스텀 헤더를 사용할 수 있는가? -
Access-Control-Allow-Credentials: 쿠키 등 인증 정보를 포함한 요청을 허용할 것인가?
4. CORS 에러를 해결하는 올바른 방법
프론트엔드에서 해결하려고 애쓰기보다, 서버 측 설정을 변경하는 것이 정석입니다.
-
서버에서 헤더 설정: Node.js(Express), Spring, Django 등 백엔드 프레임워크에서 제공하는 CORS 미들웨어를 사용하여 허용할 도메인을 명시합니다.
주의: 보안을 위해
Access-Control-Allow-Origin: *보다는 실제 서비스하는 도메인만 명시하는 것이 좋습니다. -
프록시(Proxy) 서버 사용: 개발 환경에서는 프론트엔드 개발 서버(Webpack Dev Server 등)의 프록시 기능을 이용해 브라우저를 속이는 방식을 사용할 수 있습니다.
-
API 게이트웨이 활용: 인프라 수준에서 Nginx나 API Gateway 설정을 통해 CORS 헤더를 일괄 관리할 수 있습니다.
5. 결론: 요약 및 제언

CORS는 웹 생태계의 유연성과 보안 사이의 타협점입니다.
-
정의: 다른 출처 간의 리소스 공유를 허용하는 브라우저 정책입니다.
-
원리: 브라우저가 서버에 확인 요청(Preflight)을 보내고, 서버의 응답 헤더를 보고 실행 여부를 결정합니다.
-
해결: 서버 응답 헤더에 적절한
Access-Control-Allow-*설정을 추가하는 것이 정답입니다.
[함께 읽어볼 만한 주제]
-
Nginx에서 CORS 설정 최적화하기
-
Spring Boot에서
@CrossOrigin어노테이션 활용법 -
보안의 완성: CSP(Content Security Policy)와 CORS의 시너지
전문가 코멘트: “CORS 에러가 나요!”라는 말은 곧 “내 브라우저가 보안 수칙을 아주 잘 지키고 있어요!”라는 뜻입니다. 당황하지 말고 서버의 헤더 설정을 확인해 보세요.