IT/웹서비스

CORS 를 알아야 하는 이유

엔지니어 문 2023. 1. 4. 16:04

CORS(Cross-Origin Resource Sharing)는 웹 개발의 중요한 부분으로, 다양한 도메인 간에 자원을 공유할 수 있는 안전한 방법을 제공합니다. CORS의 구현은 서버가 특정 출처에서 오는 요청을 허용하도록 설정하는 HTTP 헤더를 포함시키는 방법으로 이루어집니다. 이런 설정은 웹 개발자와 서버 관리자가 협력하여 구현해야 할 필수적인 부분입니다. 웹 개발에 있어 CORS는 단순히 기술적인 요소를 넘어서, 보안, 접근성, 그리고 법적 책임을 모두 아우르는 중요한 개념입니다. 개발자는 CORS를 이해하고 올바르게 구현하여, 사용자와 클라이언트에게 안전하고 효과적인 웹 경험을 제공해야 합니다.

이 글에서는 CORS가 무엇인지, 왜 중요한지, 그리고 이를 이해해야 하는 이유를 설명하겠습니다.

 

CORS 란 무엇인가?

 CORS(Cross-Origin Resource Sharing)는 웹 페이지에서 실행되는 스크립트가 다른 출처의 자원에 접근할 수 있도록 허용하는 보안 메커니즘입니다. 이는 웹 보안의 핵심 원칙인 같은 출처 정책(Same-Origin Policy)을 보완합니다. 같은 출처 정책은 웹 브라우저가 동일 출처(같은 프로토콜, 호스트, 포트를 사용)에서만 리소스를 불러오도록 제한하는 보안 정책입니다. CORS는 이 정책의 엄격함을 완화하여, 안전한 방식으로 출처가 다른 리소스와의 상호작용을 가능하게 합니다.

 예를 들어, https://example.com에서 서비스되는 웹 페이지가 https://api.example.com에서 데이터를 가져오려 할 때, 두 URL의 도메인이 다르기 때문에 기본적으로는 이러한 요청이 불가능합니다. CORS는 이런 제한을 안전하게 우회할 수 있는 방법을 제공합니다.

 

CORS 작동 방식

 CORS는 HTTP 헤더를 사용하여 브라우저와 서버 간에 출처 간 리소스 공유 규칙을 협상합니다. 기본적으로, 웹 애플리케이션이 다른 도메인의 리소스에 접근하려고 할 때, 브라우저는 서버에 사전 요청(pre-flight request)을 보냅니다. 이 사전 요청은 OPTIONS 메소드를 사용하여 서버에게 추가 정보 없이 리소스에 접근할 수 있는지를 묻는 것입니다.

이 요청에 대한 서버의 응답에는 다음과 같은 CORS 관련 헤더가 포함될 수 있습니다:

 Access-Control-Allow-Origin: 이 헤더는 해당 리소스에 접근할 수 있는 출처를 명시합니다. 특정 도메인을 명시하거나 모든 도메인을 의미하는 * (와일드카드)를 사용할 수 있습니다.

 Access-Control-Allow-Methods: 서버가 허용하는 HTTP 메소드(예: GET, POST 등)를 명시합니다.

 Access-Control-Allow-Headers: 서버가 허용하는 헤더를 명시합니다.

 Access-Control-Allow-Credentials: 쿠키나 HTTP 인증 정보 등 을 사용한 요청을 허용할지 여부를 명시합니다. 이 헤더가 true로 설정된 경우, Access-Control-Allow-Origin 헤더에는 *를 사용할 수 없습니다.

더보기

PlantUML 코드

@startuml

participant Browser
participant "Server (api.example.com)"

== Simple Request ==
Browser -> "Server (api.example.com)": GET /resource
note right: Request from origin\nexample.com
"Server (api.example.com)" -> Browser: HTTP 200 OK\nAccess-Control-Allow-Origin: example.com

== Preflight Request ==
Browser -> "Server (api.example.com)": OPTIONS /resource
note right: Preflight request for POST method
"Server (api.example.com)" -> Browser: HTTP 200 OK\nAccess-Control-Allow-Origin: example.com\nAccess-Control-Allow-Methods: POST, GET
Browser -> "Server (api.example.com)": POST /resource
"Server (api.example.com)" -> Browser: HTTP 200 OK\nAccess-Control-Allow-Origin: example.com

@enduml

 

 

1. 단순 요청 (Simple Request):

브라우저가 GET 요청을 보냅니다. 이는 일반적인 HTML, CSS, 이미지 파일 등의 간단한 리소스 요청에 해당합니다.

서버는 Access-Control-Allow-Origin 헤더를 포함하여 응답합니다. 이 헤더는 요청을 보낸 출처(example.com)가 서버의 리소스에 접근할 수 있음을 명시합니다.

2. 프리플라이트 요청 (Preflight Request):

POST와 같이 특별한 메소드, 헤더, 또는 withCredentialstrue로 설정된 요청은 브라우저에 의해 사전에 검사 됩니다.

브라우저는 OPTIONS 메소드를 사용하여 서버에 사전 요청을 보냅니다. 이는 서버에게 실제 요청을 보내도 안전한지 확인하는 과정입니다.

서버는 허용하는 메소드와 출처를 포함하여 응답합니다.

사전 요청이 성공하면, 브라우저는 실제 POST 요청을 보냅니다.

 

CORS가 중요한 이유

1. 보안 유지: CORS는 악의적인 사이트가 사용자 데이터를 훔치거나 불법적인 행위를 수행하는 것을 방지하면서도, 필요할 때 안전하게 자원을 공유할 수 있도록 합니다.

2. API 활용성 증가: 많은 웹 서비스가 API를 통해 데이터를 제공합니다. CORS를 이해하고 구현하면, 다양한 출처에서 자신의 서비스에 접근하도록 허용할 수 있습니다.

3. 개발 편의성: 개발 중에 자주 발생할 수 있는 다양한 출처의 리소스를 통합하는 문제를 해결할 수 있습니다.

 

CORS를 이해해야 하는 이유

개발 효율성: CORS를 이해하면, 웹 애플리케이션을 더 빠르고 효율적으로 개발할 수 있습니다. 문제를 신속하게 진단하고 해결할 수 있는 능력은 프로젝트 시간을 단축시키고, 고객 만족도를 높일 수 있습니다.

규제 준수: 많은 국가와 산업에서 데이터 보호 및 개인 정보 보호 규정을 엄격히 적용하고 있습니다. CORS는 이러한 법적 요구사항을 준수하는 데 중요한 역할을 할 수 있습니다.

시스템 통합: 대규모 시스템을 개발하거나 여러 시스템을 통합할 때 CORS를 이해하면, 다양한 시스템 간의 상호작용을 더 잘 관리할 수 있습니다.

 

CORS 이슈 사례 정리

CORS(Cross-Origin Resource Sharing) 이슈는 웹 개발 중 흔히 마주치는 문제 중 하나입니다. 이러한 이슈들은 다양한 상황에서 발생할 수 있으며, 그에 따른 해결책도 다양합니다. 아래에서는 몇 가지 일반적인 CORS 이슈 사례와 그 해소 방안을 정리해 보겠습니다.

사례 1: API 요청 거부

상황: 프론트엔드 코드가 https://example.com에서 호스팅 되고 있으며, https://api.example.com에서 제공하는 API에 요청을 보내고 있습니다. 이때 브라우저가 요청을 차단합니다.

해소 방안:

1. 서버 설정 변경: API 서버의 응답 헤더에 Access-Control-Allow-Origin: https://example.com를 추가하여 명시적으로 요청을 허용합니다.

2. 프락시 서버 사용: 개발 중에는 프론트엔드 서버를 프락시로 설정하여 API 요청을 중계할 수 있습니다. 예를 들어, 개발 서버의 설정에서 /api 경로를 https://api.example.com으로 리디렉션 하는 방법이 있습니다.

 

사례 2: 자격 증명이 포함된 요청

상황: 사용자 인증 정보(Cookies, Authentication headers 등)를 포함하여 크로스-도메인 API 요청을 보내려고 할 때 차단됨.

해소 방안:

1. 헤더 설정 추가: 서버의 응답 헤더에 Access-Control-Allow-Credentials: true와 함께 Access-Control-Allow-Origin을 명시적으로 설정해야 합니다. 여기서 주의할 점은 Access-Control-Allow-Origin와일드카드(*)를 사용할 수 없다는 것입니다.

2. 클라이언트 설정 조정: XMLHttpRequest 또는 Fetch API를 사용하는 클라이언트 코드에서 withCredentials 속성을 true로 설정해야 합니다.

 

사례 3: 다양한 HTTP 메소드 사용

상황: POST, PUT, DELETE와 같은 다양한 HTTP 메소드를 사용하는 요청을 보낼 때 특정 메소드가 차단됨.

해소 방안:

1. 프리플라이트 요청 대응: 서버에서는 CORS 프리플라이트 요청을 처리할 수 있어야 합니다. 이를 위해 OPTIONS 요청에 대한 응답으로 Access-Control-Allow-Methods에 필요한 HTTP 메소드들을 포함시켜야 합니다.

 

사례 4: 제한된 헤더 사용

상황: 사용자 정의 헤더를 요청에 포함시킬 때 브라우저가 요청을 차단합니다.

해소 방안:

1. 허용 헤더 명시: 서버의 응답 헤더에 Access-Control-Allow-Headers를 설정하여 요청에서 사용된 헤더들을 명시적으로 허용해야 합니다.

 

읽어보면 좋을만한 블로그