CORS란
date
Oct 1, 2023
slug
cors
status
Published
tags
CORS
summary
type
Post
시작하며
최근 백엔드 팀이 마이크로서비스 아키텍처(MSA)로 전환하는 과정에 참여하게 되었습니다. 제 역할은 여러 서비스에 대한 어드민 관리를 하나의 플랫폼에서 수행하는 프로젝트를 담당하는 것이었습니다.
프로젝트를 진행하는 동안, 저는 각 서비스별 CORS 허용을 백엔드 개발자들에게 지속적으로 요청해야만 했습니다. 이러한 반복되는 요청은 비효율적으로 느껴졌고, 이를 해결하고 백엔드 팀과 공유하기위해 CORS에 대해 알아보았습니다.
웹 생태계에는 다른 출처로의 리소스 요청을 제한하는 두가지 정책이 존재합니다.
- SOP: Same-Origin Policy
- CORS: Cross-Origin Resource Sharing
SOP (Same-Origin Policy)
SOP는 같은 출처인 경우에만 리소스 요청을 보낼 수 있습니다. 출처 (Origin)
- 프로토콜(Scheme): 웹 페이지에 접근하는데 사용되는 프로토콜입니다 (ex. HTTP, HTTPS)
- 호스트(Host): 웹 서버의 주소입니다. (ex. www.example.com)
- 포트(Port): 웹 서버와 통신하는데 사용되는 포트입니다. (HTTP인 경우 80, HTTPS인 경우 443)
같은 프로토콜, 호스트, 포트를 가지고 있을때 같은 출처로 판단합니다.
동일 출처가 아닌 경우의 접근을 차단하는 주된 이유는, XSS(Cross-Site Scripting)와 같은 보안 위협으로부터 웹 보안을 강화하기 위함입니다.
출처 비교 및 차단은 "브라우저"에서 수행되며, 이는 "브라우저"에 구현된 표준 규격에 따릅니다. 따라서, CORS Error는 브라우저의 SOP에 의해 다른 출처의 리소스가 차단될 때 발생합니다.
반면,
CORS는 다른 출처의 리소스에 접근하기 위한 해결책으로, 다른 출처의 리소스에 접근할 수 있도록 허용하는 방안입니다.CORS (Cross-Origin Resouce Sharing)
CORS는 다른 출처인 경우에도 리소스 요청을 보낼 수 있습니다.접근제어 시나리오
- Simple Request
- Preflight Request
- Credentialed Reqeust
단순 요청 (Simple Request)
특정 조건을 만족할 때 CORS의 사전 요청(preflight) 과정을 거치지 않고 직접 요청을 보냅니다.
- HTTP 메서드
- GET
- HEAD
- POST
- 자동으로 설정 한 헤더 외에 수동으로 설정할 수 있는 헤더
- Accept
- Accept-Language
- Content-Language
- Content-Type
- Content-Type
- application/x-www-form-urlencoded
- multipart/form-data
- text/plain
사전 요청 (Preflight Request)
브라우저는 본 요청을 보내기 전에
OPTIONS 메서드를 사용하여 사전 요청을 보냅니다. 이 과정은 서버에게 실제 요청이 안전한지 미리 확인하는 과정입니다. - 요청 헤더 목록
- Origin
- Access-Control-Request-Method
- Access-Control-Request-Headers
실제 요청에서 사용될 HTTP 메서드
실제 요청에서 사용될 사용자 지정 헤더
- 응답 헤더 목록
- Access-Control-Allow-Origin
- Access-Control-Allow-Methods
- Access-Control-Allow-Headers
- Access-Control-Allow-Credentials
- Access-Control-Max-Age
- Access-Control-Expose-Headers
허용하는 출처
허용하는 메서드
허용하는 사용자 지정 헤더
쿠키와 같은 인증 정보를 함께 요청을 보낼 수 있는지 여부
Preflight 요청의 결과를 얼마 동안 캐시할 수 있는지를 나타내는 시간
브라우저가 접근할 수 있는 서버의 응답 헤더
서버는 이 사전 요청에 대해 허용 여부를 응답합니다. 허용된 경우에만 실제 요청이 이루어집니다.
인증 정보가 포함된 요청 (Credentialed Request)
CORS 요청에서 쿠키와 같은 인증 정보를 보내지 않습니다. 따라서, 이를 포함시키려면 요청에서 withCredentials 속성을 true로 설정해야 합니다.
서버는 이러한 요청을 허용하려면, CORS 응답 헤더에 Access-Control-Allow-Credentials: true를 포함시켜야 하며, Access-Control-Allow-Origin 헤더에 구체적인 출처를 명시해야 합니다. (와일드카드 * 사용 불가)
마치며
결과적으로, 백엔드팀과 논의하여 서브도메인을 제외하고, 동일한 도메인에서의 요청에 대해서는 CORS를 허용하는 방식으로 전략을 수정했습니다. 이러한 변경을 통해 CORS 도메인 허용을 위한 반복적인 요청을 줄일 수 있었습니다. 이 글이 여러분의 프로젝트에 도움이 되기를 바랍니다. 앞으로도 유용한 정보를 공유하기 위해 노력하겠습니다.
