본문 바로가기

개발

CORS - Cross-Origin Resource Sharing 란 무엇일까

Cross-Origin Resource Sharing 

업무를 하다가 듣기는 엄청 듣고 뭔지도 대충 아는데 정확하게 설명할 정도로는 모르는것 같아서 이참에 정리한다.

 

한글로 이해 할려고 하지말고 Cross-Origin Resource Sharing 그대로 이해하자

cors 는 웹 애플리케이션이 다른 도메인 또는 포트에서 리소스에 접근할 수 있도록 허용하는것이다. 

뭔지 모르겠으면 이게 왜 나왔는지 알아가면된다. 

 

만약 어떤 개발자가 www.만화.com 사이트를 만들었다고 하자

저 사이트는 유명하고 트래픽도 많아서 저 사이트를 배끼기 위한

www.복제.com 을 만들었다.

‘복제’ 사이트는 원조 사이트의 url을 그대로 호출해서 만들었다.

이렇게 되면 원래 사이트에서 제공하는 요청이 다른 사이트에 노출된다.

예를 들어 ‘만화’ 도메인을 가진 사이트에서 get으로 만화정보를 요청하는 api가 있다고 해보자

‘복제’ 사이트에서는 이걸 그대로 쓰고 싶어서 똑같이 요청 하면 요청이 간다.

이것(=도메인이 사이트에서 요청하는것)을 방지하기 위한 기술이 Same-Origin Policy(동일 출처 정책) 이다.

여기서 ‘동일 출처’란 도메인이나 서브도메인, 프로토콜, 포트가 같은곳을 말한다.

말 그대로 Same-Origin 에 하는 요청만을 허용하는것이다.

웹 환경이 진화하면서 Same-Origin 이 아니라 Cross Origin 에서 요청하는것을 허용하기도 해야하는데

이 정책이 CORS (Cross-Origin Resource Sharing) 다.

 

정리

Same-Origin Policy - Origin이 같은곳 에서만 접근을 허용

Cross-Origin Resource Sharing - Origin이 다른 곳에 요청 보내는 것을 허용

  • Origin : 도메인이나 서브도메인, 프로토콜, 포트가 같은곳
  • Origin에 대한 더 자세한 설명은 찾아보자

크로스 오리진 요청에는 크게 2가지가 있다.

Simple Requests 와 Preflighted Requests

  1. 안전한 요청(Simple Requests):
    • safe 메서드: GET, HEAD, POST 중 하나
    • safe 헤더: Content-Type, Accept, Accept-Language, Content-Language 중 하나만 사용됨
  2. 그 외의 요청(Preflighted Requests)
    • 위의 조건을 만족하지 않는 요청
    • 커스텀 헤더가 사용되거나, GET, HEAD, POST 외의 다른 HTTP 메서드가 사용됨
    • put이나 등등

 

Simple Requests는 왜 안전한 메서드를 GET, HEAD, POST 로 정의 했을까

HTTP 프로토콜에서 GET, HEAD, POST 는 멱등성을 제공한다.

멱등성이란 같은 요청을 여러 번 보내더라도 그 결과가 동일하게 유지되는 성질이다.

멱등성을 가지고 있기 때문에 Simple Requests로 포함이 될수 있다.

반대로 멱등성을 가지고 있지 않은 Requests 는

preflight request 는 브라우저가 preflight request를 보내고 서버가 이를 허용해야 실제 요청이 전송된다.

 

안전한 요청 예시

www.만화.com 사이트에서 www.복제.com 에 요청을 허용해준다고 해보자

허용한다면 다음과 같이 동작된다.

  1. ‘복제’ 사이트에서 ‘만화’로 요청할때 Origin header에 Origin(도메인·프로토콜·포트) 정보가 담겨서 요청을 보낸다.
  2. ‘만화’ 서버는 요청 헤더에 있는 Origin를 검사한다.
  3. ‘만화’ 서버에서 ‘복제’ 서버의 요청을 받아들이기로 동의한 상태
  4. ‘만화’ 서버에서 Access-Control-Allow-Origin를 응답에 추가한다.
  5. Access-Control-Allow-Origin 응답으로 www.복제.com or  *로 응답한다
  6. Access-Control-Allow-Origin 허용되는 Origin을 보내준다
  7. Access-Control-Allow-Method 허용되는 메서드를 보내준다
  8. Access-Control-Max-Age 를 설정하면 브라우저는 일정 기간 동안 preflight 요청을 생략한다.

이 과정에서 브라우저는 중재인의 역할을 한다.

  1. 브라우저는 크로스 오리진 요청 시 Origin에 값이 제대로 설정, 전송되었는지 확인합니다.
  2. 브라우저는 서버로부터 받은 응답에 Access-Control-Allow-Origin이 있는지를 확인해서 서버가 크로스 오리진 요청을 허용하는지 아닌지를 확인합니다. 응답 헤더에 Access-Control-Allow-Origin이 있다면 자바스크립트를 사용해 응답에 접근할 수 있고 아니라면 에러가 발생한다

 

Preflighted Requests 

OPTIONS 메서드를 통해 다른 도메인의 리소스로 HTTP 요청을 보내 실제 요청이 전송하기에 안전한지 확인

preflight 은 안전한 요청에서 하나의 스텝이 더 추가된다.

 

1단계(preflight 요청)

본 요청을 보내기 전에 브라우저는 자체적으로 다음과 같은 preflight 요청을 보냅니다.

 

2단계(preflight 응답)

서버는 상태 코드 200과 함께 다음과 같은 헤더를 담은 응답을 보냅니다.

Access-Control-Allow-Methods: PATCH

Access-Control-Allow-Headers: Content-Type,API-Key

이렇게 응답이 와야 비로소 본 요청을 보낼 수 있습니다.

그렇지 않으면 에러가 발생 여기 까지가 이슈를 처리 하기 위한 기본지식이다.

 

핫한 chat.openai.com 는 어떻게 처리하는지 알아보자

gpt 사이트는 아래 처럼 되어있다.

Access-Control-Allow-Origin: https://chat.openai.com

다른 Origin 에서 요청하면 안된다.

https://chat.openai.com 여기서만 요청이 와야 허용이 된다. 

 

내가 본 이슈는 request에서 option 요청이 많이 왔는데,

Access-Control-Max-Age (브라우저는 일정 기간 동안 preflight 요청을 생략)를 쓰는것도 방법이다.

 

출처 : https://ui.toast.com/weekly-pick/ko_20211110

https://ko.javascript.info/fetch-crossorigin#ref-1185

https://developer.mozilla.org/ko/docs/Web/HTTP/CORS

반응형