CORS

July 19, 2022

교차 출처 리소스 공유(Cross-Origin Resource Sharing) 란

CORS란?

교차 출처 리소스 공유(Cross-Origin Resource Sharing, CORS)

추가적인 http header를 사용해서 서로 다른 도메인의 자원에 접근할 수 있는 권한을 브라우저에 표시해주는 체제


앞서 Origin의 개념을 먼저 살펴볼 필요가 있는데

Origin은 출처의 의미로 Protocol + Host + Port 이 3가지가 합쳐진 것을 뜻한다.

Protocol, Host, Port 가 무엇인지 알기 위해 URL의 구성을 보자.

cors-1

서로 자원을 공유받는 도메인의 Protocol + Host + Port 가 일치한다면 cors에러가 발생하지 않는다.

즉, Origin이 일치할 경우 CORS 에러가 발생하지 않는다는 의미이다.

하지만 아래와 같은 도메인이 자원을 주고받으려고 하는 경우에서는 cors에러가 발생한다.

http://localhost:8080      ----------------------     http://localhost:3000

프로토콜과 호스트는 일치하지만 포트가 다르기때문에, Origin이 일치하지 않는다고 브라우저에서 판단하여 CORS 에러가 발생한다.

그렇다면 CORS는 어떤 동작원리로 에러를 발생시키는 것일까?


CORS의 동작원리

  1. 웹 어플리케이션에서 다른 출처의 리소스를 요청하는 경우 HTTP 프로토콜을 사용해서 요청을 보낸다.
  2. 이 과정에서 브라우저는 요청 헤더 속 Origin 이라는 필드에 출처를 함께 담아보낸다.
  3. 서버에선 요청에 대한 응답을 전달한다.
  4. 이 때 response header에 Access-Control-Allow-Origin 이란 값을 보낸다.
  5. 응답을 받은 브라우저에선 보낸 요청의 Origin과 서버의 response header 속 Access-Control-Allow-Origin을 비교해 본 다음 유효한 응답인지 아닌지를 결정한다.

cors 요청 방식 3가지를 살펴보자면

  1. Simple request

서버에게 바로 본 요청을 전송하는 방식으로 요청에 대한 응답으로 서버가 헤더에**Access-Control-Allow-Origin** 를 확인하여 브라우저가 CORS 동작을 수행을 검토한다.

cors-2

위 그림처럼 Simple request은 브라우저에서 서버로 API요청을 보내고, 서버에선 Access-Control-Allow-Origin 헤더를 포함한 응답을 브라우저에 보낸다. 브라우저는 **Access-Control-Allow-Origin** 헤더를 확인해서 CORS 동작을 수행할지 판단한다.

Simple request 조건

  • 요청 메소드는 GETHEADPOST 중 하나만 가능하다.
  • AcceptWidth, Accept-LanguageContent-LanguageDownlinkContent-TypeDPR, Save-DataViewport-Width 외의 다른 헤더를 사용하면 안된다.
  • 만약 **Content-Type**를 사용하는 경우엔 text/plain, **multipart/form-data, application/x-www-form-urlencoded**만 허용된다.

  1. Preflight request
    Simple request 와 달리 options 메서드로 서버에 사전 검증 후 요청을 보내는 방법이다.

cors-3

브라우저에서 options 메서드를 통해 사전 요청을 보내고 서버에선 어떤 것을 허용, 금지할지의 정보를 헤더에 담아 보내주게 되는데 이러한 방식은 안정성을 조금 더 보장받을 수 있다.


  1. Credentialed Request

이 방식은 인증된 요청을 사용하는 방법으로 보안이 강화된 방법이다.

XMLHttpRequest 객체, fetch API는 브라우저에서 제공하는 비동기 리소스 요청API인데 이 것은 브라우저의 쿠키정보, 인증관련 헤더를 기본적으로 요청에 담지 않지만 credentials 옵션을 통해 요청에 담을 수 있도록 허용 한다.

  • credentials 옵션은 아래 3가지가 있다.

    • same-origin : 같은 출처 간 요청에만 인증 정보를 담는다.
    • include : 모든 요청에 인증 정보를 담는다.
    • omit : 모든 요청에 인증 정보를 담지 않는다.

정리

  • CORS는 서로 다른 도메인간에 자원을 공유하는 것을 의미하며 기본적으로 차단되어 있다.
  • CORS가 있기 때문에 도메인간 자원을 공유할 때 최소한의 안전에 대한 보장을 받을 수 있다.
  • 크롬과 같은 브라우저에서는 보안을 위해 스크립트에서 시작되는 Cross-Origin HTTP 요청을 제한한다.
  • 다른 출처의 리소스를 불러오려면 그 출처에서 올바른 CORS 헤더를 포함한 응답을 반환해야한다.
  • CORS는 Simple request, Preflight request, Credentialed Request 이 3가지 방법이 있다.

참조

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

https://velog.io/@pilyeooong/CORS란-무엇인가

https://evan-moon.github.io/2020/05/21/about-cors/