본문으로 바로가기

CORS(Cross Origin Resource Sharing)란?

category Web 2020. 3. 6. 23:05

제가 개발할 때 가장 난감했던 문제인데

한번 이해하고 해결하고 나면!

똑같은 상황이 생겨도 당황하지 않고 해결할 수 있더라구요 ㅇㅅㅇㅎ

cors가 뭔지 포스팅하겠습니다.


1. CORS(Cross Origin Resource Sharing)란?

Cross-Site Http Request를 가능하게 하는 표준 규약입니다.

다른 도메인으로부터 리소스가 필요할 경우 cross-site http request가 필요합니다.

기존 XMLHttpRequest는 보안상의 이유로 Same Origin Policy를 적용해

자신과 동일한 도메인으로만 HTTP요청을 보내도록 제한하였습니다.

 

즉 cross-origin http 요청을 제한했습니다.

프로토콜, 호스트명, 포트가 같아야만 요청이 가능한 것 입니다.

 

하지만 지속적으로 웹 애플리케이션을 개선하고 쉽게 개발하기 위해서는 이러한 request가 꼭 필요했습니다.

그래서 XMLHttpRequest가 cross-domain을 요청할 수 있도록하는 방법이 필요하게 되었고

W3C에서 CORS라는 이름의 권고안을 냈습니다.

 

추가적인 HTTP header를 사용해서 애플리케이션이 다른 origin의 리소스에 접근할 수 있도록 하는 메커니즘입니다.

 

2. CORS 요청의 종류

  • Simple Request
    : 서버에 1번 요청하고, 서버도 1번 회신하는 것으로 응답이 종료
    • GET, HEAD, POST 중 한가지 방식을 사용해야 함
    • POST 방식일 경우 Content-type이 아래 셋 중 하나여야 함
      • application/x-www-form-urlencoded
      • multipart/form-data
      • text/plain
    • 커스텀 헤더를 전송하지 말아야함
  • Preflight Request
    • Simple Request 조건에 해당하지 않으면 해당 방식으로 요청
      • application/xml 처럼 다른 Content-type으로 요청을 보낼 수 있음
      • 커스텀 헤더 사용 가능
    • 예비 요청과 본 요청으로 나뉘어 전송됨
      ( 예비 요청과 본 요청에 대한 서번단의 응답을 프로그래머가 프로그램 냄에서 구분하여 처리하는 것은 아님)
  • Request with Credential
    • HTTP Cookie와 HTTP Authentication 정보를 인식할 수 있게 해주는 요청
      • 요청 시 xhr.withCredentials = true를 지정해서 요청을 보낼 수 있음
      • Response Header에 반드시 Access-Control-Allow-Credentials:true를 포함해야 함
      • Access-Control-Allow-Origin 값을 *로 주면 에러 발생
  • Request without Credential
    • CORS 요청은 기본적으로 Non-Credential 요청이므로,
      xhr.withCredentials = true를 지정하지 않으면 이 요청이다.

3. 요청 헤더 목록

  • Origin
    • Cross-site요청을 날리는 요청 도메인 URI를 나타내며, access control이 적용되는 모든 요청 헤더에 반드시 포함됨
  • Access-Control-Request-Method
    • preflight요청을 할 때 실제 요청에서 어떤 메서드를 사용할 것인지 서버에게 알리기 위해 사용됩니다.
    • POST, GET, DELETE 등이 포함될 수 있음
  • Access-Control-Request-Headers
    • 예비 요청을 보낼 때 포함된다.
    • preflight요청을 할 때 실제 요청에서 어떤 header를 사용할 것인지 서버에게 알리기 위해 사용됩니다.

4. 응답 헤더 목록

  • Access-Control-Allow-Origin
    • 브라우저가 해당 origin이 자원에 접근할 수 있도록 허용합니다.
    •  *은 credentials이 없는 요청에 한해서 모든 origin에서 접근이 가능하도록 허용합니다.
  • Access-Control-Expose-Headers
    • 브라우저가 액세스할 수있는 서버 화이트리스트 헤더를 허용합니다.
    • 브라우저에 노출이 되는 HTTP Response Header 종류
      • Cache-Control
      • Content-Language
      • Content-Type
      • Expires
      • Last-Modified
      • Pragma
  • Access-Control-Max-Age
    • 얼마나 오랫동안 preflight요청이 캐싱 될 수 있는지를 나타낸다.
  • Access-Control-Allow-Credentials
    • Credentials가 true 일 때 요청에 대한 응답이 노출될 수 있는지를 나타냅니다.
    • preflight요청에 대한 응답의 일부로 사용되는 경우 실제 자격 증명을 사용하여 실제 요청을 수행 할 수 있는지를 나타냅니다.
    • 간단한 GET 요청은 preflight되지 않으므로 자격 증명이 있는 리소스를 요청하면 헤더가 리소스와 함께 반환되지 않으며
      브라우저에서 응답을 무시하고 웹 콘텐츠로 반환하지 않습니다.
  • Access-Control-Allow-Methods
    • preflight요청에 대한 대한 응답으로 허용되는 메서드들을 나타냅니다.
    • GET, POST, DELETE, PATCH 등이 존재
  • Access-Control-Allow-Headers
    • 예비 요청에 대한 Response Header에 사용된다.
    • preflight요청에 대한 대한 응답으로 실제 요청 시 사용할 수 있는 HTTP 헤더를 나타냅니다.

참고 사이트

- https://brownbears.tistory.com/336

- https://hannut91.github.io/blogs/infra/cors

'Web' 카테고리의 다른 글

OAuth 2.0 이란?  (0) 2020.03.10
동기(Synchronous)&비동기(Asynchronous)  (0) 2019.11.06
HTTP 프로토콜 이란?  (0) 2019.07.16
Web이란?  (0) 2019.07.08
서버 사이드 렌더링 (SSR) & 클라이언트 사이드 렌더링 (CSR)  (4) 2019.06.07