티스토리 뷰

Frontend

CORS란?

예둥 2024. 5. 15. 21:10

CORS란?

교차 출처 리소스 공유(Cross-Origin Resource Sharing, CORS)는 웹 애플리케이션에서 발생하는 보안 정책 중 하나입니다. 이는 웹 애프리케이션의 동일 출처 정책(Same-Origin Policy)을 우회하기 위한 매커니즘으로(서로 다른 Origin에서 리소스를 로드할 수 있도록 하는 매커니즘), 다른 출처(프로토콜, 도메인, 포트)로부터의 리소스 요청을 허용하는 방법을 정의합니다.

 

기본적으로 브라우저는 보안상의 이유로 스크립트에서 온 요청의 출처가 같은지 확인합니다. 다른 출처에서의 요청은 일반적으로 차단됩니다. 그러나 CORS를 통해 다른 출처에서의 요청을 허용할 수 있습니다.

 


프로토콜(scheme), 도메인(host), 포트 번호가 모두 일치하면 동일 출처(Same Origin)이며, 하나라도 일치하지 않는다면 교차 출처(Cross-Origin)가 된다.


 CORS가 필요한 이유

CORS가 없이 모든 곳에서 데이터를 요청할 수 있게 되면, 다른 사이트에서 원래 사이트를 흉내낼 수 있게 됩니다. 개발자 도구만 열더라도 DOM, JavaScript 코드 등 각종 통신 정보를 쉽게 열람할 수 있고, 예를 들어서 기존 사이트와 완전히 동일하게 동작하도록 하여 사용자가 로그인을 하도록 만들고, 로그인했던 세션을 탈취하여 악의적으로 정보를 추출하거나 다른 사람의 정보를 입력하는 등 공격을 할 수 있습니다. 이렇게 공격을 할 수 없도록 브라우저에서 보호하고, 필요한 경우 에만 서버와 협의하여 요청할 수 있도록 하기 위해서 필요합니다.


Same-Origin-Policy(동일 출처 정책)란?

웹에는 크게 SOP(Same Origin Policy)CORS(Cross-Origin Resource Sharing) 두 가지 정책이 있다.  SOP는 같은 출처에서만 리소스를 공유할 수 있다는 규칙을 가진 정책이다.

 

Postman과 같은 다른 서버에서 API를 호출할 때는 잘 동작하다가 브라우저에서 API를 호줄할 떄만 CORS Policy 오류가 발생한 적 있을 것이다. 이유는 브라우저가 동일 출처 정책을 지키고 있기 때문다른 출처의 리소스 접근을 금지하고 있기 때문이다. 다만 브라우저에서만 오류가 발생한 이유는 CORS가 브라우저의 구현 스펙에 포함되는 정책이기 때문에 브라우저를 통하지 않고 서버 간 통신을 할 떄는 적용되지 않기 때문이다.


CORS 동작원리

CORS의 동작 방식은 단순 요청 방법예비 요청을 먼저 보내는 방법 2가지 방법이 있습니다.

 

Simple request

단순 요청 방법은 서버에게 바로 요청을 보내는 방법입니다. 아래 그림은 자바스크립트에서 API를 요청할 때 브라우저와 서버의 동작을 나타내는 그림입니다.

 

단순 요청은 서버에 API를 요청하고, 서버는 Access-Control-Allow-Origin 헤더를 포함한 응답을 브라우저에 보냅니다. 브라우저는 Access-Control-Allow-Origin 헤더를 확인해서 CORS 동작을 수행할지 판단합니다.

 

Simple request 조건

서버로 전달하는 요청이 아래의 3가지 조건을 만족해야 단순 요청으로 동작합니다.

  • 요청 메서드는 GET, HEAD, POST 중 하나여야 합니다.
  • Accept, Accept-Language, Content-Language, Content-Type, DPR, Downlink, Save-Date, Viewport-Width, Width를 제외한 헤더를 사용하면 안됩니다.
  • Content-Type 헤더는 application/x-www-form-urlencoded, multipart/form-date, text/plan 중 하나를 사용해야 합니다.

첫 번째 조건은 어렵지 않은 조건이지만, 2번, 3번 조건은 까다로운 조건입니다. 2번 조건은 사용자 인증에 사용되는 Authorizition 헤더도 포함되지 안항 까다로운 조건이며, 3번 조건은 많은 REST API들이 Content-Type으로 application/json을 사용하기 때문에 지켜지기 어려운 조건입니다.

 

Preflight request

Preflight 요청은 서버에 예비 요청을 보내서 안전한지 판단한 후 본 요청을 보내는 방법입니다. 아래 그림은 Preflight 요청 동작을 나타내는 그림입니다.

 

GET, POST, PUT, DELETE 등의 메서드로 API를 요청했는데, 크롬 개발자 도구의 네트워크 탭에 OPTIONS 메서드로 요청이 보내지는 것을 보신 적 있으시다면 CORS를 경험하셨던 것입니다. Preflight 요청은 실제 리소스를 요청하기 전에 OPTIONS라는 메서드를 통해 실제 요청을 전송할지 판단합니다.

 

OPTIONS 메서드로 서버에 예비 요청을 먼저 보내고, 서버는 이 예비 요청에 대한 응답으로 Access-Control-Allow-Origin 헤더를 포함한 응답을 브라우저에 보냅니다. 브라우저는 단순 요청과 동일하게 Access-Control-Allow-Origin 헤더를 확인해서 CORS 동작을 수행할지 판단합니다.


CORS 에러 해결하기

Access-Control-Allow-Origin 세팅

가장 대표적인 방법은 서버에서 Access-Control-Allow-Origin 헤더에 알맞은 값을 세팅하는 것이다.

예를 들어, 서버가 특정 출처('https://example.lcom')에서의 요청을 허용하도록 하려면 다음과 같이 헤더를 설정할 수 있습니다.

Access-Control-Allow-Origin: https://example.com

 

이렇게 설정된 서버는 'https://example.com'에서 온 요청에 대해 리소스에 접근 할 수 있는 권한을 부여합니다. CORS는 웹 애플리케이션 간에 자원 공유를 허용하면서도 보안을 유지하기 위해 사용됩니다.