WIL | 22/08/14

개뉸·2022년 8월 14일
0

WIL

목록 보기
4/9
post-thumbnail

CORS

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

한 출처에서 실행중인 웹 어플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는
권한을 부여하도록 브라우저에 알려주는 체제이다.
자신의 출처(도메인,프로토콜,포트) 와 다를 때 교차 출처 HTTP 요청을 실시한다.

예를들어서 프론트 엔드 서버에서 자바스크립트 코드가 XMLHttpReqeust 를 사용하여 백 엔드의
서버에 어떤 API로 요청을 했다고 가정해보자.
보안상의 이유로 브라우저는 자바스크립트에서 시작한 교차 출처 HTTP 요청을 제한한다.
이렇게 다른 출처의 리소스를 불러오고 싶으면 올바른 CORS 헤더를 포함한 응답을 반환해야 한다.

어떤 요청이 CORS를 사용할까?

  • XMLHttpReqeust 와 Fetch API 호출
  • 웹 폰트(CSS 내 @font-face에서 교차 도메인 폰트 사용 시)
  • WebGL 텍스쳐
  • drawImage() (en-US)를 사용해 캔버스에 그린 이미지/비디오 프레임
  • 이미지로부터 추출하는 CSS Shapes.

CORS 실패는 오류의 원인이지만, 보안상의 이유로 JavaScript에서는 오류의 상세 정보에 접근할 수 없으며, 알 수 있는 것은 오류가 발생했다는 사실 뿐이다다.
정확히 어떤 것이 실패했는지 알아내려면 브라우저의 콘솔을 봐야 한다.

단순 요청

예를들어, https://foo.example 의 웹 컨텐츠가 https://bar.other 도메인의 컨텐츠를 호출하길 원한다고 해보자.
foo.example에 배포된 자바스크립트에는 아래와 같은 코드가 사용될 수 있다.

const xhr = new XMLHttpRequest();
const url = 'https://bar.other/resources/public-data/';

xhr.open('GET', url);
xhr.onreadystatechange = someHandler;
xhr.send();

클라이언트와 서버간에 간단한 통신을 하고, CORS 헤더를 사용하여 권한을 처리한다.
이 경우 브라우저가 서버로 전송하는 내용을 살펴보고, 서버의 응답을 확인한다.

GET /resources/public-data/ HTTP/1.1
Host: bar.other
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:71.0) Gecko/20100101 Firefox/71.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Connection: keep-alive
Origin: https://foo.example <---------이거주목

요청받은 헤더이다. 여기서 헤더의 Origin 항목을 보면 https://foo.example로부터 요청이 왔다는 것을 알 수 있다.

HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 00:23:53 GMT
Server: Apache/2
Access-Control-Allow-Origin: *
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/xml

[…XML Data…]

서버는 이에 대한 응답으로 Access-Control-Allow-Origin 헤더를 다시 전송한다.
가장 간단한 접근 제어 프로토콜은 Origin 헤더와 Access-Control-Allow-Origin 을 사용하는 것이다.
이 경우 서버는

Access-Control-Allow-Origin: *

으로 응답해야 하며, 이는 모든 도메인에서 접근할 수 있음을 의미한다.
https://bar.other 의 리소스 소유자가 오직 https://foo.example 의 요청만 리소스에 대한 접근을 허용하려는 경우 다음을 전송한다.

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

이제 https://foo.example 이외의 도메인은 cross-site 방식으로 리소스에 접근할 수 없다. 리소스에 대한 접근을 허용하려면, Access-Control-Allow-Origin 헤더에는 요청의 Origin 헤더에서 전송된 값이 포함되어야 한다.

이 외에도 프리플라이트 요청, 인증정보를 포함한 요청 등이 있다.

HTTP 응답 헤더

이 섹션에서는 Cross-Origin 리소스 공유 명세에 정의된 대로 서버가 접근 제어 요청을 위해 보내는 HTTP 응답 헤더가 나열한다.

- Access-Control-Allow-Origin

단일 출처를 지정하여 브라우저가 해당 출처가 리소스에 접근하도록 허용한다. 또는 자격 증명이 없는 요청의 경우 "*"

와일드 카드는 브라우저의 origin에 상관없이 모든 리소스에 접근하도록 허용한다.
예를들어 https://mozilla.org 의 코드가 리소스에 접근 할 수 있도록 하려면 다음과 같이 지정할 수 있다.

Access-Control-Allow-Origin: https://mozilla.org

- Access-Control-Expose-Headers

브라우저가 접근할 수 있는 헤더를 서버의 화이트리스트에 추가할 수 있다.

Access-Control-Expose-Headers: <header-name>[, <header-name>]*

예를들면

Access-Control-Expose-Headers: X-My-Custom-Header, X-Another-Custom-Header

X-My-Custom-Header 와 X-Another-Custom-Header 헤더가 브라우저에 드러나게된다.

- Access-Control-Max-Age

이 헤더는 preflight request 요청 결과를 캐시할 수 있는 시간을 나타낸다. preflight request 에 대한것은 출처를 찾아가서 확인하자. 나는 단순 요청의 경우만 취급했다.

Access-Control-Max-Age: <delta-seconds>

delta-seconds 파라미터는 결과를 캐시할 수 있는 시간(초)를 나타낸다.

- Access-Control-Allow-Credentials

이 헤더는 credentials 플래그가 true일 때 요청에 대한 응답을 표시할 수 있는지를 나타낸다. preflight request에 대한 응답의 일부로 사용하는 경우, credentials을 사용하여 실제 요청을 수행할 수 있는지를 나타낸다.
simple GET requests(단순 요청)는 preflighted되지 않으므로 credentials이 있는 리소스를 요청하면, 이 헤더가 리소스와 함께 반환되지 않는다.
이 헤더가 없으면 브라우저에서 응답을 무시하고 웹 컨텐츠로 반환되지 않는다는 점을 주의해야 한다. Credentialed requests 은 출처에서 확인하자.

Access-Control-Allow-Credentials: true

- Access-Control-Allow-Methods

이 헤더는 리소스에 접근할 때 허용되는 메서드를 지정한다.
이 헤더는 preflight request에 대한 응답으로 사용된다.
요청이 preflighted 되는 조건은 출처에서 확인하자.

Access-Control-Allow-Methods: <method>[, <method>]*

- Access-Control-Allow-Headers

프리플라이트 요청에 대한 응답으로 Access-Control-Allow-Headers 헤더가 사용된다.
실제 요청시 사용할 수 있는 HTTP 헤더를 나타낸다.

Access-Control-Allow-Headers: <header-name>[, <header-name>]*

HTTP 요청 헤더

이 섹션에는 cross-origin 공유 기능을 사용하기 위해 클라이언트가 HTTP 요청을 발행할 때 사용할 수 있는 헤더를 적어놓는다.
이 헤더는 서버를 호출할 때 설정된다.
cross-site XMLHttpRequest 기능을 사용하는 개발자는 프로그래밍 방식으로 cross-origin 공유 요청 헤더를 설정할 필요가 없다.

- Origin

Origin 헤더는 cross-site 접근 요청 또는 preflight request의 출처를 나타낸다.

Origin: <origin>

origin 은 요청이 시작된 서버를 나타내는 URI 이다.
경로 정보는 포함하지 않고, 오직 서버 이름만 포함한다. null 값이 올 수 있다.
어쨌든 접근 제어 요청에는 항상 Origin 헤더가 전송된다.

- Access-Control-Request-Method

Access-Control-Request-Method 헤더는 실제 요청에서 어떤 HTTP 메서드를 사용할지 서버에게 알려주기 위해, preflight request 할 때에 사용된다.

Access-Control-Request-Method: <method>

이것도 프리플라이트 요청에 사용하므로 사용 예제는 출처에서 확인하자.

- Access-Control-Request-Headers

Access-Control-Request-Headers 헤더는 실제 요청에서 어떤 HTTP 헤더를 사용할지 서버에게 알려주기 위해, preflight request 할 때에 사용된다.

Access-Control-Request-Headers: <field-name>[, <field-name>]*

이것 역시 프리플라이트 요청에 사용되므로 사용 예제는 출처에서 확인하자.

브라우저 호환성

출처 : https://developer.mozilla.org/ko/docs/Web/HTTP/CORS

0개의 댓글