CORS

coolchaem·2021년 10월 11일
1

Browser

목록 보기
2/3

CORS(Cross-Origin Resource Sharing)

  • 교차 출처 리소스 공유
  • 출처가 다르면 리소스 접근 권한을 부여하도록 browser에서 설정한 정책이다.
    • 간단히 말하면, 보안 정책이다. 보안 상 cross site 요청은 해킹에 취약한 것으로 보인다. 그래서 CORS를 적용하여 보다 안전하게 리소스에 접근해야 한다고 한다.
  • Web app이 리소스가 자신의 출처(domain, protocol, port)와 다를 때 교차 출처 HTTP requset를 실행해야만 한다.
  • 기본적으로 브라우저는 same origin security policy를 권장하는 것으로 보인다. 그러나, 실제 서비스를 하다보면 불가능하다고 한다.

리소스 추가 설명

  • 문서, 이미지, 스크립트 등
  • 리소스 위치는 URI(Uniform Resource Identifier)로 식별된다.
    • URL(Uniform Resource Locator)이 일반적 형식이다.
    • 형식은 protocol://domainName:port/resourcePath?query#fragment 으로 리소스를 구분한다.
      • protocol: http, https, ssh, file, ...
      • domainName: velog.io, ...
      • port: 80, 8000, ...
      • resourcePath: Web server에서 file 경로 (ex. usr/list/1.html)
      • query: Web server에게 전달할 parameter
      • fragment: 리소스 내부에서 쪼개진 단위가 있는 거스올 보인다. 특정 구간을 가리키는 id로 해석된다.
  • CORS를 사용하는 request 종류
    • Fetch, XMLHttpRequest API
    • Web font(CSS 내 @font-face에서 cross domain font 사용 시)
    • WebGL texture
    • drawImage()로 canvas에 그린 image/video frame
    • CSS Shapes from images

CORS 시나리오

  • CORS 동작은 크게 3가지 시나리오로 나뉜다.

1. Preflight 방법

  • 리소스를 공유해도 되는지 미리 확인하는 절차이다.
  • 출처가 다르지만 리소스를 공유할 수 있는 권한을 주는 과정을 의미한다.
  • HTTP OPTION request method를 사용한다.
    • 서버가 승인하면, 클라이언트는 실제 HTTP request를 보낸다.
    • cross-site requests를 서버에서 지원하지 않으면 에러를 respond한다.
  • 예제
// Preflight 이용한 요청 code
const xhr = new XMLHttpRequest();
xhr.open('POST', 'https://bar.other/resources/post-here/');
xhr.setRequestHeader('Ping-Other', 'pingpong');
xhr.setRequestHeader('Content-Type', 'application/xml');
xhr.onreadystatechange = handler;
xhr.send('<person><name>Arun</name></person>');

2. Simple requests 방법

  • preflight 방법이 아닌 서버가 자동으로 특정 조건을 충족하는 request message를 받으면 CORS 관련 헤더를 포함해 response message를 보낸다.
const xhr = new XMLHttpRequest();
const url = 'https://bar.other/resources/public-data/';

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

HTTP message

HTTP message는 특정한 포맷으로 작성되어야 한다.
w3c에서 스펙으로 지정한 형식이 있는데, reqeust/response 메시지 내용이 다르다.
List of HTTP header fields


3. credentialed requests

  • HTTP cookies, HTTP authentication 정보를 담은 request를 생성하면 된다.
  • 서버가 Access-Control-Allow-Credentials: true를 응답해주면 된다.
const invocation = new XMLHttpRequest();
const url = 'https://bar.other/resources/credentialed-content/';

function callOtherDomain() {
  if (invocation) {
    invocation.open('GET', url, true);
    invocation.withCredentials = true; // credentials option
    invocation.onreadystatechange = handler;
    invocation.send();
  }
}

출처

Cross-Origin Resource Sharing (CORS)
Identifying resources on the Web
Cross-origin resource sharing

profile
Front-end developer

0개의 댓글