1) 한 문장 요약

브라우저는 보안을 위해 “다른 출처(origin)”에서 온 요청을 제한한다.
CORS는 서버가 응답 헤더로 어떤 출처에서의 요청을 허용할지(또는 거부할지) 선언하는 표준 메커니즘이다.
2) 용어 정리
- Origin(출처) = scheme://host:port (예: https://www.example.com, http://localhost:3000)
- Same-Origin Policy = 브라우저 기본 보안 정책. 동일 출처끼리만 자원 공유 허용
- CORS = 서버가 응답 헤더로 허용 출처/메서드/헤더 등을 명시해 브라우저가 예외를 허용하게 하는 규칙
- Preflight(사전요청) = 브라우저가 실제 요청 전에 OPTIONS 요청으로 서버가 허용하는지 확인하는 단계
- Credentialed request = 쿠키·HTTP 인증 정보가 포함된 요청 (fetch에서 credentials: 'include')
3) CORS가 동작하는 흐름 (단계별, 그림 없이 텍스트로)
1. 프론트가 https://frontend.com에서 https://api.service.com/data로 요청을 보냄
2. 브라우저는 요청 유형에 따라 두 가지로 행동:
- Simple request(단순 요청): GET, POST(특정 content-type) 등 브라우저가 바로 요청을 보내고, 응답 헤더에 Access-Control-Allow-Origin이 없으면 콘솔에서 차단(데이터는 받아오지 못함)
- Preflight required(사전요청 필요): PUT, DELETE, 맞춤 헤더가 있을 때 등. 브라우저가 먼저 OPTIONS 요청(Preflight)을 보냄. 서버가 OPTIONS에 올바르게 응답해야 실제 요청이 전송됨
- 서버는 응답에 CORS 관련 헤더를 포함. 브라우저는 이 헤더를 읽고 “허용”이면 JS가 응답에 접근하도록 허용, 아니면 차단
4) 핵심 응답 헤더 (서버가 설정해야 하는 것들)
- Access-Control-Allow-Origin: https://frontend.com
- 또는 모든 출처 허용: * (주의: credentials와 함께 쓸 수 없음)
- Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
- Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With
- Access-Control-Allow-Credentials: true (쿠키·인증정보 허용 시)
- Access-Control-Max-Age: 86400 (preflight 결과 캐시 시간(초))
- Vary: Origin (Origin별로 응답이 달라질 수 있음을 캐시/프록시에게 알리기)
5) Preflight(OPTIONS) 자세히
- 브라우저가 보내는 OPTIONS 요청 (예: OPTIONS /api/data HTTP/1.1 with Origin header)
- 서버는 빈 바디로 아래 같은 헤더들로 응답해야 실제 요청
- Access-Control-Allow-Origin, Access-Control-Allow-Methods, Access-Control-Allow-Headers, Access-Control-Allow-Credentials(필요 시)
- Preflight가 실패하면 브라우저 콘솔에 Access to fetch at '...' from origin '...' has been blocked by CORS policy 같은 에러가 뜸
6) credentials (쿠키/인증) 관련 주의
- Access-Control-Allow-Credentials: true 를 쓸 때는 Access-Control-Allow-Origin: *을 사용할 수 없다. 반드시 구체적 origin을 반환해야 함(혹은 동적으로 echo)
- 프런트 측에서 요청 시 fetch(url, { credentials: 'include' }) 또는 XHR에서 withCredentials = true 설정 필요
- 쿠키와 세션 유지가 중요한 로그인 흐름(SSO 포함)은 CORS와 세션 정책을 함께 설계해야 함
7) 실무 체크리스트
(개발 요청서나 회의에서 반드시 확인·공유할 항목)
1. 도메인 목록: 프론트(웹/모바일 웹), 백오피스, API, 스태틱, 이벤트 도메인 등
2. 어떤 API가 누가 호출하는지(웹, 앱, 서버사이드): 클라이언트에서 호출하는 API는 CORS 필요
3. 인증 방식: 토큰 기반(JWT)인가? 세션·쿠키 기반인가? (cookie → credentials 이슈)
4. 허용 메서드: 어떤 HTTP 메서드가 필요한가? (PUT, DELETE는 preflight 발생)
5. 커스텀 헤더: Authorization, X-Client-Id 등 커스텀 헤더가 있나? → preflight 발생
6. 개발/스테이지/프로덕션 별 정책: env별로 허용 origin을 다르게 할지 결정
7. 외부 연동: 결제·OAuth·광고 등 외부 서비스에서 리다이렉트/콜백 도메인 확인
8. 프록시 여부: 서버 사이드에서 프록시/게이트웨이로 처리할 수 있는지 검토(브라우저 CORS를 우회 가능)
8) 요약
- CORS는 브라우저 보안 모델에 기반한 서버-클라이언트 상호작용 규칙이다.
- 기획자는 도메인 설계·인증 방식·외부 연동을 설계할 때 CORS를 꼭 고려하고 개발팀과 명확히 공유해야 한다.
- 개발자는 서버에서 적절한 CORS 헤더(특히 origin, methods, headers, credentials)를 정확히 설정하고 preflight를 처리해야 한다.
- 디버깅은 브라우저 네트워크 탭과 curl로 응답 헤더를 직접 확인하면 대부분 해결된다.
'CS' 카테고리의 다른 글
| 데이터 바인딩(Data Binding)이란 무엇인가 (0) | 2026.01.02 |
|---|---|
| API Gateway (API 게이트웨이) (0) | 2025.11.12 |
| 클라이언트-사이드 렌더링(CSR) vs 서버-사이드 렌더링(SSR) (0) | 2025.10.31 |
| 세션(Session) (0) | 2025.10.09 |
| 익스터널 링크(External Link) (0) | 2025.10.03 |