Published on

Cross Origin Resource Sharing(CORS)

Authors
  • avatar
    Name
    Luffy Yeon
    Twitter

Cross Origin Resource Sharing(CORS)

XMLHttpRequest(XHR) 보안상의 이유로 같은 도메인으로만 HTTP 요청이 가능하도록 제한되어있다.
하지만 웹 애플리케이션 발전으로 도메인간의 요청 제한은 개발에 많은 불편함을 야기 시켰다고 한다.
예로는 img, link, script 태그로 다른 도메인 리소스를 요청하는 경우가 있다. 그래서 생긴 새로운 표준규약 Cross Origin Resource Sharing(CORS), 다른 도메인으로 부터 리소스를 요청할 수 있도록 제한을 결정 할 수 있도록 생김.


CORS 방식

CORS 방식에는 크게 네가지가 있다.

  • Simple Request
  • Preflight Request
  • Credential
  • Non-Credentail

Simple Request

간단한 요청으로 클라이언트가 서버에 요청, 서버 회신으로 처리 완료된다.

  • GET, HEAD, POST 요청중 한가지 사용
  • POST 인경우 content-type (application/x-www-form-urlencoded, multipart/form-data, text/plain)
  • 커스텀 헤더 전송 X
HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 00:23:53 GMT
Server: Apache/2.0.61
Access-Control-Allow-Origin: *
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/xml

Access-Control-Allow-Origin: * 모든 도메인으로부터 접근이 가능
Access-Control-Allow-Origin: http://foo.client.com 허용 도메인 지정


Preflight Request

Simple Request 조건에 만족하지 않는다면 브라우저는 Preflight Request 방식으로 요청한다.

  • GET, HEAD, POST 외의 요청
  • POST인 경우 Simple Request content-type 외의 Type (application/xml)
  • 커스텀 헤더 전송인 경우

클라이언트에서 서버로 예비요청(Preflight Request)를 보내고 서버에서 응답을 받는다.
그 다음 실제요청(Actual Request)를 서버로 보내고 서버에서 응답을 받는다.


예비요청은 OPTION을 이용하여 요청되며 어떤 요청이 전달될지 미리 알려준다.

OPTIONS /resources/post-here/ HTTP/1.1
Host: bar.other
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
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
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
Origin: http://foo.example
Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-PINGOTHER

Access-Control-Request-Method: POST 실제 요청에서 POST가 요청될 것을 알려준다.
Access-Control-Request-Headers: X-PINGOTHER 실제 요청에서 전달될 헤더 정보.


이후 서버 응답


HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 01:15:39 GMT
Server: Apache/2.0.61 (Unix)
Access-Control-Allow-Origin: http://foo.example
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: X-PINGOTHER
Access-Control-Max-Age: 1728000
Vary: Accept-Encoding, Origin
Content-Encoding: gzip
Content-Length: 0
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Content-Type: text/plain

Access-Control-Allow-Origin: http://foo.example
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: X-PINGOTHER
허가된 정보들을 응답 받는다.


Credential

HTTP 쿠키와 HTTP Authentication 정보를 인식하게 해주는 요청이며 withCredentials을 true 값으로 설정해주면 된다.

var xhr = new XMLHttpRequest()
var url = 'http://bar.other/resources/credentialed-content/'
function callOtherDomain() {
if (xhr) {
xhr.open('GET', url, true)
xhr.withCredentials = true
xhr.onreadystatechange = handler
xhr.send()
}
}

서버와 인증을 하기를 원하는 클라이언트는 Authorization 요청 헤더 필드에 인증 정보를 포함함으로써 인증을 수행할 수 있다.


Non Credential

withCredentials 기본 값은 false이며 withCredentials를 설정하지 않은 모든 요청은 Non Credential로 본다고한다.