HTTP CORS(교차 출처 리소스 공유)

JUNGHUN KIM·2021년 8월 7일
0
post-custom-banner

CORS는 브라우저와 서버간의 안전한 교차 출처 요청 및 데이터 전송을 지원한다.

CORS (Cross-Origin Resource Sharing)

출처 또는 포트가 다른 서버의 리소스를 요청하는 메커니즘

  • 추가 HTTP 헤더를 사용하여 한 출처에서 실행중인 웹 애플리케이션이 다른 출처의 자원에 접근 할 수 있는 권한을 부여하는 것.
  • 교차라는 보다는 다른 출처라는 말이 조금더 이해하기 쉽다.
  • 간단히 이야기하면 서로 다른 출처(Origin)간 리소스를 공유한다는 의미

브라우저간 데이터를 주고 받는 과정에서 도메인 이름이 서로 다른 사이트에서 api요청을 할 경우(대게 요청은 HTTP로 한다.) 공유 설정을 하지 않는다면 CORS에러가 발생

CORS 에러를 해결하기 위해서는 데이터를 주고받는 api요청을 할 때,
요청과 응답하는쪽의 헤더에 특정한 값을 설정하게 되면 CORS에러를 해결할 수 있다.

출처(Origin)란..?

서버의 위치를 의미하는 URL들은 하나의 문자영리 아닌 여러개의 구성요소가 합쳐진 것인데, 출처(Origin)은 Protocol과 Host, 그리고 포트번호가 합쳐진 것을 의미한다.

예시

https: //www.naver.com/

  • Protocol : https: //
  • Host : www.naver.com
  • 포트번호 : 여기서는 포트번호가 생략되어져 있지만 대게 Host뒤에 온다.
    (ex: https:www.google.com:440

CORS의 동작

  1. 브라우저가 요청 헤더에 Origin이라는 필드에 요청을 보내는 출처를 함께 담아 보냄
  2. 요청을 받은 서버가 이 요청에 대한 응답을 할 때 응답 헤더의 "Access-Control-Allow-Origin"이라는 값으로 리소스에 접근을 허용하는 출처를 내려줌.
  3. 응답을 받은 브라우저는 자신이 보냈던 요청의 Origin과 서버가 내려준 응답의 Access-Control-Allow-Origin을 비교한 후 응답이 유효한지 결정한다.

예시

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은 요청한 출처를 의미하며 Host는 다른 출처를 의미

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

예시를 보면 HTTP GET 요청으로 Orgin: https://foo.example을 보내고 있으며
이에 대한 응답으로 Access-Control-Allow-Origin: * 를 전달받음

이때 *의 의미는 모든 출처에서 리소스에 액세스 할 수 있음을 의미함.

CORS 동작 시나리오

1. Simple Request

일부 요청의 경우 CORS Preflight를 트리거 하지 않는데 이 경우는 Simple Reqest라고 한다.

1.예비 요청없이 서버에게 본 요청을 서버에게 바로 요청
2.서버가 이에 대한 응답의 헤더에 Access-Control-Allow-Origin 값을 보냄
3. 응답을 전달받은 브라우저가 CORS정책 위반 여부를 검사하는 방식

Prefilght Reqest와 Simple Reqest는 전반적인 로직은 같지만 예비 요청만 없음

Simple Reqest는 아무때나 사용할 수 있는 것이 아닌, 특정 조건을 모두 만족하는 경우에만 예비 요청을 생략할 수 있다. (조건이 까다롭기 때문에 대부분 충족못함)

Simple Reqest의 조건

1.요청의 메소드는 GET, HEAD, POST 중 하나여야 한다.
2. Accept, Accept-Language, Content-Language, Content-Type, DPR, Downlink, Save-Data, Viewport-Width, Width를 제외한 헤더를 사용하면 안된다.
3. 만약 Content-Type를 사용하는 경우에는 application/x-www-form-urlencoded, multipart/form-data, text/plain만 허용된다.

2. Prefilght Request

일반적으로 웹 애플리케이션 개발할 때 가장 많이 마주치는 시나리오이며, 이 시나리오에 해당하는 상황일 경우, 브라우저는 요청을 한번에 보내지 않고 예비요청과 본 요청으로 나누어서 서버에 전송한다.

이때 예비 요청을 Preflight라고 부르며 예비 요청은 HTTP OPTIONS메소드를 이용해서 보낸다. 예비 요청은 본 요청을 보내기전에 이 요청이 안전한지 확인하는 것.

브라우저는 서버에게 예비 요청을 먼저 보내고, 서버는 이 예비 요청에 대한 응답으로 현재 자신이 어떤 것들을 허용하고, 어떤 것들을 금지하고 있는지에 대한 정보를 응답 헤더에 담아서 브라우저에게 다시 보내준다.

이후 브라우저가 자신이 보낸 예비 요청과 서버가 응답에 담어준 허용 정책을 비교한 후 이 요청을 보내는것이 안전하다고 판단되면 동일한 경로에 본 요청을 보낸다.

CORS 관련 헤더 내용

헤더에 알맞게 내용을 기재하면되며, 이 헤더의 내용같은경우는 req,res에 모두 기재가 가능하다.

  • Access-Control-Allow-Origin: 어떤 Origin을 허용할 것인가 , *로하면 모든경로
  • Access-Control-Allow-Methods: 어떤 method를 허용할 것인가
  • Access-Control-Allow-Headers: 어떤 header를 허용할 것인가
  • Access-Control-Max-Age: 얼마나 자주 Prefilght message를 보낼 것인가

참조

https://evan-moon.github.io/2020/05/21/about-cors/#preflight-request
https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

profile
개발자가 되고 싶은 일문학도
post-custom-banner

0개의 댓글