CORS(Cross Origin Resource Sharing)

2022. 5. 22. 15:13
반응형

CORS(Cross Origin Resource Sharing)

Origin

프로토콜 + 호스트 + 포트번호

Cross Origin과 Same Origin

  • Same Origin : 프로토콜, 호스트, 포트번호가 동일한 URI
  • Cross Origin : Same Origin이 아닌 URI

Q. 다음중https://helloworld.com 과 동일 출처(Same Origin)이 아닌것은?

  1. https://helloworld.com:8080
  2. http://helloworld.com
  3. https://helloworld.com/members

동일 출처(Same Origin)이 되려면 프로토콜, 호스트, 포트번호가 동일해야 하므로 정답은 3번이다. 나머지 1,2번은 Cross Origin이라고 할 수 있다.

CORS

  • 정의 : 한 출처에서 실행중인 웹 애플리케이션이 다른 출처의 자원에 접근할 수 있도록 브라우저에 알려주는 체제이다.
  • 방식 : 자신과 다른 출처의 리소스를 불러오려면 그 출처에서 올바른 CORS 헤더를 포함한 응답을 반환해줘야 한다.
  • 요청 : 웹 애플리케이션은 리소스가 자신의 출처(프로토콜, 도메인, 포트 번호)와 다를 때, 교차 출처 HTTP 요청을 실행한다.
  • 목적 : 브라우저와 서버간의 안전한 교차출처 요청 및 데이터 전송을 지원함으로써 교차출처 HTTP 요청의 위험을 완화시킨다.

CORS 동작방식

1. Simple Requests

Simple Requests는 아래의 조건들을 만족해야 사용할 수 있다.

  1. 요청 메서드는 GET, HEAD, POST 중 하나여야 한다.
  2. Accept, Accept-Language, Content-Language, Content-Type 헤더를 제외한 헤더를 사용하면 안된다.
  3. 만약 Content-Type을 사용하는 경우 다음과 같이 3개의 타입을 허용한다.
    • application/x-www-form-urlencoded
    • multipart/form-data
    • text/plain

HTTP Request

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 Response

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 : 서버에서 허용하는 출처가 표기되어 있다. 위의 응답은 모든 도메인에서의 접근을 허용한다.
  • 만약 서버에서 https://foo.example 의 요청만을 허용하고 싶다면 다음과 같이 설정한다.
    • Access-Control-Allow-Origin: https://foo.example

이처럼 Simple Requests에서 다른 출처의 리소스에 대한 접근을 허용하려면, Access-Control-Allow-Origin 헤더에 요청의 Origin 헤더에서 전송된 값이 포함되어야 한다.

2. Preflighted Requests

  • 실제 요청과 응답을 하기전에 클라이언트에서 먼저 OPTIONS 메서드를 통해서 다른 도메인의 리소스로 HTTP 요청을 보내서 실제 요청이 전송하기에 안전한지 확인한다.
  • cross-origin 요청이 유저 데이터에 영향을 줄 수 있기 때문에 이와같이 미리 전송(Preflight)한다.

Preflighted Request

OPTIONS /doc 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
Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-PINGOTHER, Content-Type
  • OPTIONS : HTTP Method로 Preflight 요청시 사용된다.
  • Origin : 클라이언트의 출처를 밝힌다.
  • Access-Control-Request-Method : 실제 요청을 할 때, 어떤 메서드로 요청을 할 지 알린다.
  • Access-Control-Request-Headers : 실제 요청을 할 때, 해당 헤더와 함께 요청될 것을 알린다.
  • Access-Control-Request 헤더는 Preflight 요청 시에만 사용된다. 실제 요청에 대한 정보를 담기 때문에 서버가 이러한 상황에서 어떻게 반응할 지 결정하도록 할 수 있다.

Preflighted Response

HTTP/1.1 204 No Content
Date: Mon, 01 Dec 2008 01:15:39 GMT
Server: Apache/2
Access-Control-Allow-Origin: https://foo.example
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
Access-Control-Max-Age: 86400
Vary: Accept-Encoding, Origin
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
  • Access-Control-Allow-Origin : 서버에서 허용할 출처를 나타낸다.
  • Access-Control-Allow-Methods : 서버에서 허용할 메서드를 나타낸다.
  • Access-Control-Allow-Headers : 서버에서 허용하는 사용자 헤더를 알려준다.
  • Access-Control-Max-Age : 다른 preflighted request를 보내지 않고, preflighted request에 대한 응답을 캐시할 수 있는 시간을 알려준다.

Real Request

POST /doc 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
X-PINGOTHER: pingpong
Content-Type: text/xml; charset=UTF-8
Referer: https://foo.example/examples/preflightInvocation.html
Content-Length: 55
Origin: https://foo.example
Pragma: no-cache
Cache-Control: no-cache

<person><name>Arun</name></person>
  • 실제 요청에서는 서버가 허용하는 방식으로 요청을 보내는 것을 볼 수 있다.
    • POST
    • Origin
    • X-PINGOTHER, Content-Type

Real Response

HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 01:15:40 GMT
Server: Apache/2
Access-Control-Allow-Origin: https://foo.example
Vary: Accept-Encoding, Origin
Content-Encoding: gzip
Content-Length: 235
Keep-Alive: timeout=2, max=99
Connection: Keep-Alive
Content-Type: text/plain

[Some XML payload]
  • https://foo.example 은 허용된 출처이므로 200 OK 로 정상 응답을 보내준다.

3. Requests with credentials

  • 인증된 요청을 사용하는 방식이다. 즉, 다른 출처간의 보안을 강화하고 싶을 때 사용하는 방식이다.
  • HTTP Cookies와 HTTP Authentication 정보를 인식한다.
  • 브라우저가 제공하는 비동기 리소스 요청 API인 XMLHttpRequest 객체나 fetch API : 별도의 옵션 없이는 쿠키 정보나 인증과 관련된 헤더를 요청에 담지 않는다.
  • credentials : 요청에 인증과 관련된 정보를 담게 해주는 옵션으로, 다음과 같은 3개의 값을 갖는다.
    • same-origin : 기본값으로, 같은 출처 간 요청에만 인증정보를 담을 수 있다는 의미이다.
    • include : 모든 요청에 인증정보를 담을 수 있다는 의미이다.
    • omit : 모든 요청에 인증정보를 담지 않는다는 의미이다.

자세한 정보

반응형

'컴퓨터 관련 기본 지식(CS) > Network' 카테고리의 다른 글

쿠키(Cookie)와 세션(Session)  (0) 2022.04.27

BELATED ARTICLES

more