CORS는 코스요리가 아니야

김키핑·2026년 5월 5일
post-thumbnail

브라우저는 왜 특정 도메인에서 다른 자원을 가져올 수 없나

브라우저가 자원을 가져오는 방법

브라우저 → 웹서버 요청 → 웹서버가 응답 → 브라우저가 랜더링


브라우저 → 웹서버 요청

한때는 누군가의 가장 애정하는 프로젝트였지만, 불과 n주만에 그에게서 완전히 잊혀진 프로젝트
유씽크 를 살펴보자.

브라우저에서 버튼을 클릭해 유튜브 영상과 관련된 상호작용을 시도한다.


웹서버 요청 → 웹서버가 응답

브라우저에서 버튼을 클릭했을 때 해당 웹서버에 요청헤더를 사용해 HTTP 요청이 전송되었다.
이때 요청 헤더에는 Content-Type, User-Agent 등 key-value 형태의 부가 정보가 담겨 전달되고,

웹서버는 요청을 처리한 뒤 응답을 돌려주는데,
여기서 받은 200 OK는 요청이 정상적으로 처리되었고 응답 본문에 요청한 리소스가 포함되어 있다는 의미다.


웹서버가 응답 → 브라우저가 랜더링

웹서버의 응답을 받은 브라우저는
응답 헤더를 확인하고, 문제가 없으면 받은 리소스를 화면에 랜더링한다.

앞서 잠시 언급했지만 위의 예시 사진에서도 200 ok 상태코드가 있는 응답헤더를 받았으므로
멋진 리소스가 랜더링 되었을 확률이 높다.


브라우저 보안정책

200번대 상태코드 응답을 받았음에도 브라우저에 멋진 리소스가 랜더링 되었을 것이라고 확신할 수 없는 이유는 브라우저 보안정책 때문이다.

브라우저는 웹서버의 응답을 확인할 때 보안 검사도 함께 수행하는데, 보안정책에 맞지 않는 응답을 받으면 웹서버에서 200~299의 성공 상태 코드가 있는 응답이 반환되더라도 브라우저는 해당 응답을 차단하여 랜더링하지 않는다.


SOP (Same-Origin Policy, 동일 출처 정책)

여러 브라우저 정책 중, 오늘은 SOP를 중점적으로 다뤄보자.
모든 브라우저는 기본적으로 같은 출처에서 온 리소스만 허용하고, 다른 출처의 리소스는 기본적으로 차단한다.

http://yousync.kr/page/1

여기서 Origin은 무엇일까?
그렇다. yousync.kr이다.

스킴(프로토콜) + 도메인 + 포트번호를 합친것이 Origin 인 것이다.
SOP는 Origin의 구성요소 중 하나라도 다르면 다른 출처로 판단하여 리소스 접근을 차단한다.

https://yousync.kr  vs  http://yousync.kr   → 스킴 달라 ❌
https://yousync.kr vs  https://yousing.kr    → 도메인 달라 ❌
https://yousync.kr  vs  https://yousync.kr:2025 → 포트 달라 ❌

서버는 어떻게 다른 도메인의 요청을 허락해주나

CORS

브라우저가 다른 출처의 리소스 접근을 제한하는 정책(SOP, Same-Origin Policy)을 완화할 수 있도록, 서버가 특정 출처의 접근을 허가해주는 HTTP 헤더 기반 메커니즘


CORS 헤더 동작 방식

브라우저가 네트워크 요청을 처리하는 방식을 정의한 Fetch Standard 규약에 따르면, 브라우저는 서버 데이터 변형의 우려가 없는 요청은 Simple Request 로, 변형의 우려가 있는 요청은 Preflight Request 로 처리한다.

현대 API 통신은 대부분 application/json 을 사용하기 때문에 Simple Request 조건을 만족하는 경우는 거의 없고, 대부분 Preflight Request가 발생한다.


Simple Request (단순요청)

서버 데이터 변형의 우려가 없는 요청으로, 아래 조건을 모두 만족할 때 Preflight 없이 바로 요청을 보낸다.

메서드   : GET, POST, HEAD 중 하나
Content-Type : 아래 중 하나
               - text/plain
               - multipart/form-data
               - application/x-www-form-urlencoded

Preflight Request (사전요청)

Simple Request 조건을 벗어난 요청으로, 본 요청 전에 OPTIONS 메서드로 서버에 먼저 허락을 구한다.

메서드   : PUT, DELETE, PATCH 등
Content-Type : application/json 등
커스텀 헤더 : Authorization 등

브라우저가 Preflight 요청을 보내면 서버는 아래 세 가지 헤더를 담아 응답해야 한다.

Access-Control-Allow-Origin  : 허락할 출처
Access-Control-Allow-Methods : 허락할 메서드
Access-Control-Allow-Headers : 허락할 헤더

※ OPTIONS :브라우저가 Preflight 상황에서 자동으로 보낼 것으로, 수동으로 요청을 보내는 코드는 작성하지 않아도 괜찮다.


요약

Simple Request
- 브라우저 : 조건 일치 시 바로 요청
- 서버     : Access-Control-Allow-Origin 설정해야 함

Preflight Request
- 브라우저 : 조건 벗어나면 OPTIONS로 먼저 허락 구함
- 서버     : 세 가지 헤더 모두 설정해야 함
             Access-Control-Allow-Origin
             Access-Control-Allow-Methods
             Access-Control-Allow-Headers

시스터디 결론

Q.   CORS(Cross-Origin Resource Sharing)는 무엇이며 왜 필요한가요?

A.

CORS는 다른 Origin의 리소스를 브라우저에서 렌더링할 수 있도록 보안 정책을 완화해주는 HTTP 헤더 기반 메커니즘입니다.

사랑과 전쟁으로 CORS를 설명하자면,
브라우저는 남편, 다른 출처의 리소스는 여자친구, 보안 정책(SOP)은 시어머니, 서버는 시아버지입니다.

시어머니인 SOP로 인해 남편인 브라우저가 여자친구인 리소스를 만날 수 없을 때,
전세계 모든 브라우저가 네트워크 요청을 처리하는 방식에 대해 정의 되어 있는 Fetch Standard 규약에 따라 서버 데이터 변형 여부를 고려하여 단순요청 또는 사전요청을 보내면, 시아버지인 서버가 특정 출처의 접근을 허가하는 응답 헤더를 함께 보내 브라우저가 다른 Origin의 리소스를 로드할 수 있도록 해줍니다.

CORS가 없었다면 YouTube 영상 리소스를 받아와야 했던 유씽크는 시작조차 하지 못했을 것입니다.

우리 모두가 좋아했던 유씽크를 위해 CORS는 반드시 필요합니다.

반박시 님 유씽크 싫어함
이상.

++ 비유가 난해했다는 피드백을 받음.

profile
양치기소녀

0개의 댓글