이전 글에서 웹 브라우저와 서버 간 데이터 통신의 규약인 REST API란 무엇인가에 대해 알아보았습니다. 프론트엔드와 백엔드가 REST API로 데이터를 주고받을 때 웹 개발 과정에서 가장 흔하게 만나는 대표적인 오류가 바로 CORS 에러입니다.
브라우저 콘솔창에 붉은색 글씨로 뜨는 CORS 에러란 무엇인가, 해당 에러가 발생하는 원인과 보안상의 이유, 그리고 백엔드 및 프론트엔드에서의 해결 방법까지 구글 SEO 가이드라인에 맞추어 깔끔하게 정리해 드립니다.
목차
1. CORS 에러란 무엇인가? (개념 정의)
**CORS(Cross-Origin Resource Sharing, 교차 출처 자원 공유)**는 추가 HTTP 헤더를 사용하여 한 출처(Origin)에서 실행 중인 웹 애플리케이션이 다른 출처의 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알리는 메커니즘입니다.
따라서 CORS 에러는 웹 브라우저가 보안을 위해 다른 출처의 리소스 요청을 차단할 때 발생합니다. 중요한 점은 CORS 정책을 위반했는지 검사하고 차단하는 주체가 서버가 아닌 **’웹 브라우저’**라는 사실입니다.
2. SOP(동일 출처 정책)와 출처(Origin)의 의미
CORS를 이해하려면 웹 브라우저의 기본 보안 정책인 **SOP(Same-Origin Policy, 동일 출처 정책)**를 먼저 알아야 합니다.
출처(Origin)의 구성 요소
웹에서 출처(Origin)는 프로토콜(Protocol) + 도메인(Host) + 포트번호(Port) 3가지의 조합을 말합니다.
https://example.com:443/user주소에서 출처는https://example.com:443입니다.- 이 3가지 중 하나라도 다르면 브라우저는 **’다른 출처(Cross-Origin)’**로 인식합니다.
왜 SOP 정책을 사용할까?
만약 다른 출처 간의 데이터 접근이 자유롭다면, 악의적인 사이트에서 사용자의 브라우저 쿠키나 세션을 이용해 서버에 요청을 보내는 CSRF(Cross-Site Request Forgery) 공격이나 데이터 유출 사고가 발생할 수 있습니다. 브라우저는 이를 방지하기 위해 기본적으로 동일한 출처끼리만 자원을 공유하도록 제한합니다.
3. CORS가 동작하는 3가지 방식
웹 브라우저가 다른 출처로 요청을 보낼 때 CORS 허용 여부를 판단하는 방식은 크게 3가지로 나뉩니다.
| 동작 방식 | 설명 및 특징 |
|---|---|
| 예비 요청 (Preflight Request) | 본 요청을 보내기 전 OPTIONS 메서드로 서버에 예비 요청을 보내 안전한지 먼저 확인하는 가장 일반적인 방식 |
| 단순 요청 (Simple Request) | 예비 요청을 거치지 않고 바로 본 요청을 보낸 후 응답 헤더를 통해 CORS 여부를 확인하는 방식 (특정 조건 만족 필요) |
| 인증된 요청 (Credentialed Request) | 쿠키나 Authorization 헤더 등 인증 정보를 포함하여 보내는 요청으로, 보다 엄격한 보안 조건 적용 |
4. CORS 에러 해결 방법 3가지
개발 과정 및 실제 서비스 운영 중 CORS 에러를 해결하는 가장 대표적인 방법은 다음과 같습니다.
① 서버(백엔드)에서 Access-Control-Allow-Origin 헤더 설정 (정석)
CORS 문제의 근본적인 해결책은 서버 측에서 허용할 출처를 응답 헤더에 명시하는 것입니다.
- Nginx/Apache 설정: Web Server 설정 파일에서
Access-Control-Allow-Origin헤더에 허용할 도메인을 추가합니다. - Node.js (Express):
cors미들웨어를 사용하여 특정 도메인 또는 전체 도메인을 허용합니다. - Spring Boot:
@CrossOrigin어노테이션이나WebMvcConfigurer를 통해 CORS 허용 설정을 추가합니다.
// Node.js Express 예시
const cors = require('cors');
app.use(cors({
origin: '[https://my-frontend-domain.com](https://my-frontend-domain.com)' // 허용할 프론트엔드 도메인
}));