웹 개발을 하다 보면, 교차 오리진(Cross-Origin) 요청을 다루는 일이 자주 발생합니다. CORS는 웹 브라우저 기반 보안 메커니즘으로, 교차 오리진 리소스 공유(Cross-Origin Resource Sharing)의 약자입니다. 이 메커니즘을 이해하면, 클라이언트와 서버 간의 데이터를 안전하게 주고받을 수 있습니다. 이번 포스트에서는 CORS의 작동 원리와 실전에서 어떻게 적용되는지에 대해 깊이 있게 알아보겠습니다.
Origin은 URL의 프로토콜(HTTP/HTTPS), 호스트(도메인), 포트로 구성됩니다. 예를 들어, https://www.example.com
이라는 URL이 있다고 가정해보겠습니다.
https
www.example.com
443
같은 Origin을 갖는다는 것은, 이 세 가지 요소가 동일하다는 것을 의미합니다. 예를 들어, https://www.example.com
과 https://www.example.com:443
는 같은 오리진을 공유합니다. 하지만, https://www.example.com
과 http://www.example.com
은 프로토콜이 다르므로 다른 오리진으로 간주됩니다.
CORS는 웹 브라우저에서 보안을 강화하기 위해 사용하는 메커니즘입니다. 기본적으로 브라우저는 동일 오리진 정책(Same-Origin Policy)을 따르며, 이는 다른 오리진에서의 리소스 요청을 차단합니다. 하지만, CORS를 사용하면 다른 오리진에서도 리소스를 요청할 수 있습니다.
CORS의 작동 원리를 쉽게 이해하기 위해 시나리오를 하나 만들어보겠습니다. 두 개의 웹 서버가 있다고 가정해봅시다.
https://www.example.com
https://www.other.com
웹 브라우저는 첫 번째 서버인 example.com
에서 index.html
파일을 요청합니다. 이 파일은 다른 오리진에서 이미지를 가져오도록 설정되어 있습니다. 예를 들어, 이미지 파일이 other.com
에 존재한다고 가정해봅시다. 웹 브라우저는 다른 오리진에서 리소스를 가져오기 전에 먼저 사전 요청(Preflight Request)을 보냅니다. 이때, 사전 요청은 HTTP 메서드 중 OPTIONS
를 사용하여, 대상 서버(other.com
)에게 교차 오리진 요청을 허용할지를 묻습니다.
만약 other.com
이 교차 오리진 요청을 허용하도록 설정되어 있다면, 서버는 Access-Control-Allow-Origin
헤더를 통해 특정 오리진(ex: https://www.example.com
) 또는 모든 오리진을 허용하는 와일드카드(*
)를 응답합니다. 이후 브라우저는 해당 응답을 확인하고, 교차 오리진 요청을 완료합니다.
Amazon S3 버킷에 CORS를 설정하는 경우도 자주 발생합니다. S3 버킷은 정적 웹사이트 호스팅 기능을 제공하는데, 한 버킷에서 다른 버킷으로부터 리소스를 가져오려고 할 때 CORS 설정이 필요합니다.
예를 들어, 두 개의 S3 버킷이 있다고 가정해보겠습니다:
my-bucket-html
(정적 웹사이트 호스팅 활성화)my-bucket-assets
(자산 및 이미지 저장용)사용자는 브라우저에서 my-bucket-html
에 있는 index.html
파일을 요청합니다. 이 파일에는 다른 버킷에 있는 이미지를 포함하는 URL이 있습니다. 만약 my-bucket-assets
에 적절한 CORS 설정이 되어 있지 않다면, 브라우저는 이미지 요청을 차단할 것입니다.
S3에서 교차 오리진 요청을 처리하려면, S3 버킷의 CORS 설정에서 특정 오리진(예: https://www.example.com
) 또는 모든 오리진을 허용하는 *
을 허용하도록 설정해야 합니다.
CORS 설정 시 가장 중요한 요소는 HTTP 헤더입니다. 주요 헤더는 다음과 같습니다:
*
로 모든 오리진을 허용할 수 있습니다.CORS는 현대 웹 애플리케이션에서 필수적인 보안 메커니즘입니다. 특히, 서로 다른 오리진 간의 데이터 교환이 필수적인 경우, 이를 적절히 설정하는 것은 보안을 유지하면서도 원활한 사용자 경험을 제공하는 데 중요한 역할을 합니다.