CORS와 프리플라이트
CORS(Cross-Origin Resource Sharing)는 브라우저가 다른 출처(Origin)의 리소스에 접근할 때 적용하는 보안 정책입니다. Same-Origin Policy의 예외를 만드는 표준으로, 서버가 명시적으로 허용한 Origin·메소드·헤더에 한해서만 데이터를 노출합니다.
Simple Request 조건
아래 조건을 모두 만족하면 브라우저는 사전요청(Preflight) 없이 즉시 본 요청을 보냅니다.
- 메소드: GET, HEAD, POST 중 하나
- Content-Type: application/x-www-form-urlencoded, multipart/form-data, text/plain 중 하나
- 커스텀 헤더 없음 (Accept, Accept-Language, Content-Language 등 안전 헤더만 허용)
- XMLHttpRequestUpload에 이벤트 리스너를 등록하지 않음
- ReadableStream 객체를 사용하지 않음
Preflight Request 발생 조건
Simple Request 조건을 하나라도 어기면 브라우저는 본 요청 전에 OPTIONS 메소드로 사전 요청을 보내 서버 허용 여부를 확인합니다.
- PUT, DELETE, PATCH 등의 메소드
- Content-Type: application/json 사용 (가장 흔한 케이스)
- Authorization, X-API-Key 등 커스텀 헤더
주요 응답 헤더
Access-Control-Allow-Origin: 허용할 Origin (또는*)Access-Control-Allow-Methods: 허용 메소드 (Preflight 응답)Access-Control-Allow-Headers: 허용 헤더 (Preflight 응답)Access-Control-Allow-Credentials:true면 쿠키 전송 허용 (이 경우*금지)Access-Control-Max-Age: 프리플라이트 캐시 시간 (초)Access-Control-Expose-Headers: 응답에서 JS가 읽을 수 있는 커스텀 헤더 화이트리스트
CORS 트러블슈팅 체크리스트
- OPTIONS 요청에도 200/204 응답을 반환하는가? (많은 백엔드가 OPTIONS를 405로 차단)
- withCredentials=true인 요청에
Allow-Origin: *이 아닌 명시적 도메인을 반환하는가? - 커스텀 헤더가 모두 Allow-Headers에 포함되어 있는가?
- 리다이렉트가 CORS를 깨뜨리지 않는가? (302 응답의 Location 헤더 확인)
- CDN/Reverse Proxy가 CORS 헤더를 덮어쓰지 않는가?
자주 묻는 질문 (FAQ)
Q. CORS는 서버 보안 강화 수단인가요?
A. 아닙니다. CORS는 브라우저가 클라이언트(JS) 차원에서 적용하는 정책입니다. curl, Postman, 서버 간 통신에는 영향이 없습니다.
Q. Allow-Origin: * 만 설정하면 되나요?
A. 단순 공개 API라면 가능하지만, 쿠키나 Authorization을 사용하는 경우 *는 차단됩니다. 정확한 Origin을 명시해야 합니다.
Q. CORS 에러 해결을 클라이언트에서 할 수 있나요?
A. 클라이언트 측에서는 해결 불가합니다. API 서버 또는 그 앞단의 Proxy에서 헤더를 추가해야 합니다.