📚 목차
[Network] CORS(교차 출처 리소스 공유)
CORS란?
CORS
(Cross-Origin Resource Sharing, 교차 출처 리소스 공유)를 번역하면 "교차 출처 리소스 공유"이다.
여기서 출처가 교차한다는 게 무슨 뜻일까? 출처는 'origin'의 번역 표현이다. 우리가 흔히 알고 있는 URL에서 도메인만 뜻하는 게 아니라 프로토콜과 포트까지 포함하는 개념이다. 출처를 구성하는 세 요소는 Protocol, Domain(호스트 이름), Port로, 이 중 하나라도 다르면 CORS 에러를 만나게 된다.
- 도메인(Hostname): myshop.com
- 출처(Origin): https://www.myshop.com
즉, '출처가 교차한다'는 건 리소스를 주고받으려는 '두 출처가 서로 다르다'는 뜻이다. CORS를 설정한다는 건 '출처가 다른 서버 간의 리소스 공유'를 허용한다는 것을 의미한다.
위에서 SOP (Same-Origin Policy)가 서로 다른 출처일 때 리소스 요청과 응답을 차단하는 정책이라면, CORS는 반대로 서로 다른 출처라도 리소스 요청, 응답을 허용할 수 있도록 하는 정책이다. 그래서 우리가 만나는 에러는 CORS가 가능하도록 뭔가 설정하라는 내용으로 이루어져 있다.
뒤에 나올 해결 방법에서 사용되는 헤더인 Access-Control-Allow-Origin
도 '허용되는 출처에 대한 접근제어'는 의미라고 이해할 수 있다.
웹의 발달과 CORS
예전에는 프론트엔드와 백엔드를 따로 구성하지 않고 한 번에 구성해서 모든 처리가 같은 도메인 안에서 가능했다.
그래서 다른 출처로 요청을 보내는 게 의심스러운 행위로 보일 수밖에 없었다. 그런데 시간이 지나 클라이언트에서 API를 직접 호출하는 방식이 당연해지기 시작했다.
그런데 보통 클라이언트와 API는 다른 도메인에 있는 경우가 많다. 그래서 CORS 정책이 생겼다. 출처가 다르더라도 요청과 응답을 주고받을 수 있도록 서버에 리소스 호출이 허용된 출처(Origin)를 명시해 주는 방식이다.
CORS 에러 대응하기
서버에서 Access-Control-Allow-Origin 응답 헤더 세팅하기
서버에서 Access-Control-Allow-Origin
헤더를 설정해서 요청을 수락할 출처를 명시적으로 지정할 수 있다.
이 헤더를 세팅하면 출처가 다르더라도 https://myshop.com
의 리소스 요청을 허용하게 된다.
'Access-Control-Allow-Origin': <origin> | *
를 설정하면 출처에 상관없이 리소스에 접근할 수 있는 와일드카드이기 때문에 보안에 취약진다. 그래서 'Access-Control-Allow-Origin': https://myshop.com
과 같이 직접 허용할 출처를 세팅하는 방법이 더 좋다.
Proxy 서버 사용하기
웹 애플리케이션이 리소스를 직접적으로 요청하는 대신, 프락시 서버를 사용하여 웹 애플리케이션에서 리소스로의 요청을 전달하는 방법도 있다.
이 방법을 사용하면, 웹 애플리케이션이 리소스와 동일한 출처에서 요청을 보내는 것처럼 보이므로 CORS 에러를 방지할 수 있다.
예를 들어, http://example.com
에서 동작하는 웹 애플리케이션이 http://api.example.com
에 데이터를 요청하는 상황을 가정해 보자. 두 도메인이 다르기 때문에 브라우저는 cross-origin
요청으로 판단하고, 서버가 CORS 설정을 제대로 하지 않았다면 요청이 실패할 수 있다.
이 문제를 해결하려면, 웹 애플리케이션이 직접 http://api.example.com
에 API 요청하는 대신, 같은 출처(http://example.com)
에 위치한 Proxy 서버를 통해 API 요청을 중계하도록 구성하면 된다.
웹 애플리케이션 → http://example.com/api/proxy → (서버 내부 요청) → http://api.example.com
브라우저 입장에선 http://example.com
에 요청한 것처럼 보이기 때문에, CORS 검사 없이 응답을 받을 수 있다.