CORS와 SOP 이해하기

웹 개발하면서 필연적으로 만나게 되는 CORS 이슈에 대해서 정리합니다.


CORS

CORS(Cross-Origin Resource Sharing) 한국어로 직역하면 교차 출처 리소스 공유 라는 뜻으로 서로 다른 출처를 가진 서비스에서 서로 자원을 공유한다는 개념입니다.

웹 개발하면서 만나게 되는 CORS 오류는 CORS 정책을 위반하였기 때문입니다.

CORS를 이해하기 위해서는 Origin(출처)에 대해서 알아야 됩니다.


Origin(출처)

URL 구조

Origin(출처)은 URL 구조에서 Protocol, Host, Port를 합친 것을 의미하고 여기서 Port는 생략이 가능합니다.

즉, Protocol, Host, Port 부분이 일치하다면 같은 출처이고 다르다면 다른 출처라고 판단할 수 있습니다.

IE에서는 Port가 달라도 Protocol과 Host가 같다면 같은 출처라고 판단한다고 한다.

웹 사이트에서 F12로 콘솔창을 열고 아래 코드를 입력하면 해당 사이트의 Origin을 확인할 수 있습니다.

console.log(location.origin) 
//https://jeongje.vercel.app

Same-Origin Policy

보안상의 이유로, 브라우저에서는 교차 출처 HTTP 요청을 차단하고 있습니다.

예시로 XMLHttpRequestFetch APISOP(Same-Origin Policy)를 따릅니다.

SOP를 따르는 API를 사용하는 웹 애플리케이션은 자신의 출처와 동일한 리소스만 가져올 수 있습니다.

https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

위 사진으로 설명하면, domain-a.com이라는 사이트에서 domain-a.com 서버에 저장된 이미지를 가져오는 것은 같은 출처의 리소스이므로 문제가 되지 않습니다.

그러나 domain-b.com 서버에 저장된 이미지를 가져오는 것은 다른 출처의 리소스에 접근하는 것이므로 SOP에 위반됩니다.

웹 애플리케이션을 개발할 때 CSS 파일, Font 등을 외부 사이트에서 실시간으로 import해서 가져오는 경우가 흔합니다. 이런 경우 SOP는 개발 시 많은 불편을 줍니다.

SOP의 기준을 완화하여 부분적으로 다른 출처의 리소스에 접근할 수 있도록 만든 체제가 CORS입니다.


CORS Prefilght

CORS Prefilght(CORS 사전 요청)은 본격적인 교차 출처 HTTP 요청 전에 서버 측에게 해당 요청의 메서드와 헤더에 대해 인식하고 있는지를 확인하는 CORS 요청 입니다.

Simple Request

Simple Request(단순 요청)의 경우에는 CORS Prefilght를 거치지 않습니다.

단순 요청이 되기 위한 조건은 다음과 같습니다.

위 조건들을 만족하는 요청이라면 다른 출처에 향한 요청이라도 문제가 발생하지 않습니다.

그러나 위 조건도 역시 꽤 깐깐한 조건이고 그로 인해 우리가 CORS 오류를 자주 만나게 되는 겁니다.


CORS 오류 해결

교차 출처이고 SOP 조건도 맞추지 못해 CORS 오류가 발생했어도 해결 방법이 존재합니다.

· Access-Control-Allow-Origin

CORS 오류 해결에 대표적인 방법입니다. 서버에서 Access-Control-Allow-Origin 헤더에 CORS 정책에 위반되더라도 요청을 수락할 출처를 세팅하면 됩니다.

이때 많이들 *을 사용하지만 이는 모든 출처에 대해 요청을 수락하겠다는 의미이고 보안상 문제점을 일으킬 수 있습니다. CORS 정책이 귀찮기는 하지만 보안상 이점이 있는 것은 확실합니다.

· Proxy 서버 설정

Proxy 설정은 주로 프론트엔드에서 사용되는 방법으로 프론트 서버와 백 서버가 분리된 경우 브라우저에서 요청이 오면 백 서버로 가기 전에 프론트 서버를 거치게 됩니다.

이때 프론트에서 브라우저에게 받은 요청의 출처를 백이 수용 가능한 출처로 바꿔서 CORS 오류를 회피하는 방법입니다.