기타/WWW

교차출처 자원공유(Cross-origin resource sharing)

하늘이푸른오늘 2014. 1. 22. 13:38

이 문서는 영문 위키피디아를 번역한 것입니다.


====

교차출처 자원공유 (CORS : Cross-origin resource sharing) 란 어떤 웹페이지에 있는 자바스크립트가, 해당 도메인이 아닌 다른 도메인에 XMLHttpRequests 요청을 허용하는 기법을 말한다. CORS를 통하지 않을 경우, "도메인을 넘어선(cross-domain)" 요청은 동일출처정책(same origin security policy)에 의해 웹브라우저에 의해 금지된다. 교차출처 자원공유는 다른 출처에서 온 요청을 허용할 지를 결정하기 위해, 웹브라우저와 서버가 상호교류하는 방법을 정의한 것이다. CORS는 동일출처의 요청만 허용하는 것보다는 유용하지만, 모든 출처의 요청을 모두 허용하는 것보다는 안전하다.


Cross-origin resource sharing (CORS) is a mechanism that allows JavaScript on a web page to make XMLHttpRequests to another domain, not the domain the JavaScript originated from. Such "cross-domain" requests would otherwise be forbidden by web browsers, per the same origin security policy. CORS defines a way in which the browser and the server can interact to determine whether or not to allow the cross-origin request.[2] It is more useful than only allowing same-origin requests, but it is more secure than simply allowing all such cross-origin requests.


CORS의 작동 방식(How CORS works)


교차출처 자원공유(CORS) 표준은 새로운 HTTP 헤더를 추가함으로써 서버가 허용된 도메인에 자원을 제공하는 방식이다. 브라우저는 이러한 헤더를 지원하며, 설정한 제한을 강행한다.? 아울러 사용자 데이터에 부수적 효과를 일으키는 HTTP 요청 메소드(특히, GET을 제외한 HTTP 메소드 또는 특정 MIME 타입의 POST 용법)의 경우,  브라우저에서 요청에 대해 "사전점검(preflight)"하고, 서버로부터 HTTP OPTIONS 요청헤더를 사용하여 지원되는 메소드를 요청하며, 그 다음 서버로부터 "허가(approval)"을 받으면 실재 HTTP 요청 메소드를 사용하여 실재 요청을 전송하도록 강제하고 있다. 아울러 서버는 클라리언트에게 (쿠키나 HTTP 인증데이터 등의) "보증(credential)"을 요청과 함께 보내야 할지 통지할 수 있다.


The CORS standard works by adding new HTTP headers that allow servers to serve resources to permitted origin domains. Browsers support these headers and enforce the restrictions they establish. Additionally, for HTTP request methods that can cause side-effects on user data (in particular, for HTTP methods other than GET, or for POST usage with certain MIME types), the specification mandates that browsers “preflight” the request, soliciting supported methods from the server with an HTTP OPTIONS request header, and then, upon “approval” from the server, sending the actual request with the actual HTTP request method. Servers can also notify clients whether “credentials” (including Cookies and HTTP Authentication data) should be sent with requests.


간단한 예제(Simplified example)


교차출처 자원공유요청을 시작하려면, 브라우저가 Origin HTTP 헤더를 가진 요청을 전송한다. 이 헤더의 값은 페이지를 전송받을 도메인이다. 예를 들어 http://www.example-social-network.com 에 있는 어떤 페이지에서 online-personal-calendar.com 에 있는 사용자의 데이터를 접근하려고 시도한다고 가정하자. 사용자의 브라우저가 CORS를  지원한다면, 다음과 같은 헤더가 online-personal-calendar.com에 전송된다.


To initiate a cross-origin request, a browser sends the request with an Origin HTTP header. The value of this header is the domain that served the page. For example, suppose a page from http://www.example-social-network.com attempts to access a user's data in online-personal-calendar.com. If the user's browser implements CORS, the following request header would be sent to online-personal-calendar.com:


Origin: http://www.example-social-network.com


online-personal-calendar.com에서 요청을 허용한다면, 응답으로 Access-Control-Allow-Origin 헤더를 전송한다. 헤더의 값은 어떠한 사이트가 허용되는지를 가르킨다. 예를 들어, 위의 요청에 따른 응답에는 다음과 같은 내용이 들어있게 된다.


If online-personal-calendar.com allows the request, it sends an Access-Control-Allow-Origin header in its response. The value of the header indicates what origin sites are allowed. For example, a response to the previous request would contain the following:


Access-Control-Allow-Origin: http://www.example-social-network.com


교차출처 자원공유(CORS) 요청을 허용하지 않는다면, 브라우저는 online-personal-calendar.com 의 응답대신 example-social-network.com 에 에러를 전송한다. 모든 도메인의 접근을 허용할 경우에는 서버에서 다음과 같은 응답 헤더를 보낸다.


If the server does not allow the cross-origin request, the browser will deliver an error to example-social-network.com page instead of the online-personal-calendar.com response. To allow access from all domains, a server can send the following response header:


Access-Control-Allow-Origin: *


일반적으로 이렇게 하는 것은 좋지 않다. 이것이 적절한 유일한 경우는 어떤 페이지 혹은 API 응답이 완전히 공개된 경우로서, 어떤 사이트의 어떤 코드든지 누구나 접근가능하다는 뜻이다.


This is generally not appropriate. The only case where this is appropriate is when a page or API response is considered completely public content and it is intended to be accessible to everyone, including any code on any site.


"*" 값은 보증(credential) 즉, HTTP 인증, 클라이언트측 SSL 인증서 에 대한 요청을 허용하지 않으며, 쿠키 전송도 허용하지 않는다는 점에서 특별한 의미가 있다.


The value of "*" is special in that it does not allow requests to supply credentials, meaning HTTP authentication, client-side SSL certificates, nor does it allow cookies to be sent.


지원되는 브라우저(Browser support)


CORS 는 다음과 같은 레이아웃 엔진에 기초한 모든 브라우저에서 지원된다.

  • Gecko 1.9.1 (Firefox 3.5, SeaMonkey 2.0, Camino 2.1 ) 이상
  • WebKit (최초버전은 불확실, Safari 4 이상, Google Chrome 3 이상, 아마도 이전부터 지원되었을 것임)
  • MSHTML/Trident 6.0 (Internet Explorer 10)은 지원. MSHTML/Trident 4.0 & 5.0 (Internet Explorer 8 & 9) XDomainRequest 객체를 통해 일부 지원
  • Presto-based browsers (Opera) Opera 12.00 와 Opera Mobile 12 는 CORS 구현, Opera Mini는 제외


CORS 는 다음과 같은 레이아웃 엔진에 기초한 모든 브라우저에서 지원된다.

  • Gecko 1.9.1 (Firefox 3.5,SeaMonkey 2.0, Camino 2.1) 이상
  • WebKit (최초 버전은 불명, Safari 4 이상,Google Chrome 3 이상, 아마도 이전부터 지원했을 것임)
  • MSHTML/Trident 6.0 (Internet Explorer 10) 전체 지원. MSHTML/Trident 4.0 & 5.0 (Internet Explorer 8 & 9) XDomainRequest 객체를 통해서 일부 지원.
  • Presto-기반 브라우저 (Opera) 는 CORS 구현  (Opera 12.00 및 Opera Mobile 12), Opera Mini 제외


아래의 브라우저는 CORS를 지원하지않지만, 언급할 가치가 있다.

  • Camino 는 2.0.x 버전에서 CORS를 구현하지 않았다. 이 버전에서는 Gecko 1.9.0을 기반으로 작성되었기 때문이다.As of version 0.10.2, 
  • Arora는 WebKit CORS 관련 API를 공개하였으나, 교차출처 자원공유 요청은 실패한다.


아래 브라우저는 CORS를 지원하지 않지만, 특별히 언급할 가치가 있다.

  • Camino 2.x 대는 CORS 가 구현되지 않음. Gecko 1.9.0를 기반으로 했기 때문임.
  • Arora 0.10.2 의 경우, WebKit 의 CORS 관련 API를 공개했으나, 요청을 보내면 실패함


역사(History)


교차출처 자원공유는 원래 2004년 3월 Tellme Networks 의 Matt Oshry, Brad Porter, 그리고 Michael Bodell 등이 제안하였다. VoiceXML 브라우저에 의한 안전한 교차출처 데이터 요청을 허용할 수 있도록 VoiceXML 2.1에 포함시키고자하는 목적이었다. 하지만 이 메카니즘이 원래 일반적인 사항으로 VoiceXML에 국한된 것이 아니라고 여겨지자, 이후 implementation NOTE로 분리되었다. W3C 의 WebApps 워킹그룹에서는 주요 브라우저 제작사과 함께 그 NOTE를 W3C Working Draft에 포함시켜 공식화하기 시작하고 공식 W3C 추천 상태를 밟고 있다.?


Cross-origin support was originally proposed by Matt Oshry, Brad Porter, and Michael Bodell of Tellme Networks in March 2004 for inclusion in VoiceXML 2.1[14] to allow safe cross-origin data requests by VoiceXML browsers. The mechanism was deemed general in nature and not specific to VoiceXML and was subsequently separated into an implementation NOTE.[15] The WebApps Working Group of the W3C with participation from the major browser vendors began to formalize the NOTE into a W3C Working Draft on track toward formal W3C Recommendation status.


CORS와 JSONP와의 관계(CORS relationship to JSONP)


CORS는 JSONP 형태에 대한 최신 대안이 될 수 있다. JSONP는 GET 요청 메소드만 지원하지만, CORS는 다른 HTTP 유형도 지원한다. CORS를 사용하면 일반 XMLHttpRequest를 사용할 수 있다. XMLHttpRequest를 사용하면 JSONP보다 훨씬 다양한 오류처리가 가능한 장점이 있다. 반면, JSONP는 CORS를 지원하지 않는 오래된 브라우저에서도 사용할 수 있다. CORS는 최신의 웹브라우저만 지원한다. 또한 JSONP는 외부 사이트가 해킹에 노출되면 크로스사이트 스크립팅(XSS: cross-site scripting) 문제를 일으킬 수 있지만, CORS는 보안을 확보하기 위하여 개별적으로 응답을 해석하도록 한다.


CORS can be used as a modern alternative to the JSONP pattern. While JSONP supports only the GET request method, CORS also supports other types of HTTP requests. Using CORS enables a web programmer to use regular XMLHttpRequest, which supports better error handling than JSONP. On the other hand, JSONP works on legacy browsers which predate CORS support. CORS is supported by most modern web browsers. Also, while JSONP can cause cross-site scripting (XSS) issues where the external site is compromised, CORS allows websites to manually parse responses to ensure security.


=====

제가 기술에 대해 잘 모르기 때문에 공부할 요량으로 번역을 했으나, 그렇기 때문에 정확하지 않을 수 있습니다. 혹시 잘못 이해한 부분이 있다면 댓글로 남겨주시면 감사하겠습니다.


민, 푸른하늘