CORS란?
교차 출처 리소스 공유(Cross-Origin Resource Sharing, CORS)
추가적인 http header를 사용해서 서로 다른 도메인의 자원에 접근할 수 있는 권한을 브라우저에 표시해주는 체제
앞서 Origin의 개념을 먼저 살펴볼 필요가 있는데
Origin은 출처의 의미로 Protocol + Host + Port 이 3가지가 합쳐진 것을 뜻한다.
Protocol, Host, Port 가 무엇인지 알기 위해 URL의 구성을 보자.
서로 자원을 공유받는 도메인의 Protocol + Host + Port 가 일치한다면 cors에러가 발생하지 않는다.
즉, Origin이 일치할 경우 CORS 에러가 발생하지 않는다는 의미이다.
하지만 아래와 같은 도메인이 자원을 주고받으려고 하는 경우에서는 cors에러가 발생한다.
http://localhost:8080 ---------------------- http://localhost:3000
프로토콜과 호스트는 일치하지만 포트가 다르기때문에, Origin이 일치하지 않는다고 브라우저에서 판단하여 CORS 에러가 발생한다.
그렇다면 CORS는 어떤 동작원리로 에러를 발생시키는 것일까?
CORS의 동작원리
- 웹 어플리케이션에서 다른 출처의 리소스를 요청하는 경우 HTTP 프로토콜을 사용해서 요청을 보낸다.
- 이 과정에서 브라우저는 요청 헤더 속 Origin 이라는 필드에 출처를 함께 담아보낸다.
- 서버에선 요청에 대한 응답을 전달한다.
- 이 때 response header에 Access-Control-Allow-Origin 이란 값을 보낸다.
- 응답을 받은 브라우저에선 보낸 요청의 Origin과 서버의 response header 속 Access-Control-Allow-Origin을 비교해 본 다음 유효한 응답인지 아닌지를 결정한다.
cors 요청 방식 3가지를 살펴보자면
-
Simple request
서버에게 바로 본 요청을 전송하는 방식으로 요청에 대한 응답으로 서버가 헤더에**Access-Control-Allow-Origin
** 를 확인하여 브라우저가 CORS 동작을 수행을 검토한다.
위 그림처럼 Simple request은 브라우저에서 서버로 API요청을 보내고, 서버에선 Access-Control-Allow-Origin
헤더를 포함한 응답을 브라우저에 보낸다. 브라우저는 **Access-Control-Allow-Origin**
헤더를 확인해서 CORS 동작을 수행할지 판단한다.
Simple request 조건
- 요청 메소드는
GET
,HEAD
,POST
중 하나만 가능하다. Accept
,Width
,Accept-Language
,Content-Language
,Downlink
,Content-Type
,DPR
,Save-Data
,Viewport-Width
외의 다른 헤더를 사용하면 안된다.- 만약 **
Content-Type
**를 사용하는 경우엔text/plain
, **multipart/form-data
,application/x-www-form-urlencoded
**만 허용된다.
-
Preflight request
Simple request 와 달리options
메서드로 서버에 사전 검증 후 요청을 보내는 방법이다.
브라우저에서 options 메서드를 통해 사전 요청을 보내고 서버에선 어떤 것을 허용, 금지할지의 정보를 헤더에 담아 보내주게 되는데 이러한 방식은 안정성을 조금 더 보장받을 수 있다.
-
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