CORS란

twid_yuni·2023년 10월 30일
1
post-thumbnail

웹 개발을 할 때 개발자이 자주 마주치는 단어가 있습니다.

그 중 대표적인 것이 바로 CORS인데요.

오늘은 브라우저 콘솔을 노랗고 빨갛게 물들이는 이 CORS가 무엇인지 알아보겠습니다.



목차

1. CORS란
2. CORS 동작 방식  





1. CORS란? 🤔


CORS에 알려면 브라우저의 정책인 SOP에 대해 먼저 알아야 합니다.

SOP

브라우저는 기본적으로 SOP(Same origin principle) 정책을 가지고 있습니다.

SOP를 직역하면   "동일 출처 정책"으로

하나의 출처(Origin)에서 로드된 문서나 리소스가 동일한 출처에 있는 리소스에만 접근할 수 있도록 제한하는 자바스크립트 엔진 표준 스펙의 보안 규칙입니다.

다른 출처에 있는 리소스에 대한 접근은 보안상의 이유로 차단합니다.

여기서 Origin(출처)이란 [프로토콜+호스트+포트]를 합한 것으로, 이 세가지 중 하나라도 다르면 서로 다른 출처로 판단합니다.


CORS

CORS는 특정 조건을 만족시키는 경우, 출처가 다른 리소스를 공유할 수 있도록 하는 메커니즘(방법)입니다.

CORS는 SOP의 제약을 완화하여, 웹 페이지에서 다른 출처의 리소스에 안전하게 접근할 수 있도록 합니다.



 SOP는 다른 출처에서의 리소스 접근을 제한하는 보안 정책

CORS는 다른 출처의 리소스를 불러올 수 있도록 하는 방법






2. CORS 동작 방식 🌐


위에서 CORS의 개념을 설명할 때 특정 조건을 만족하면 다른 출처의 리소스를 불러올 수 있다고 하였습니다.

이 특정 조건이 무엇인지 알아보겠습니다.


결론부터 말하자면,
브라우저는 http 응답에 Access-Control-Allow-* 헤더의 내용이 http 요청의 내용과 일치하지 않는 경우, CORS 에러를 발생시킵니다.



응답 헤더를 언제 검증하느냐에 따라 CORS 동작 방식은 2가지 정도로 분류됩니다.



1) preflight request


preflight request?

클라이언트가 서버로 요청을 보내기 전에 preflight request라는 CORS 검증 요청을 먼저 보낸 다음,
진짜 요청을 보내는 방법입니다.

클라이언트는 preflight 요청을 통해 서버에서 허용하는 HTTP Method, Origin, Header 등을 알 수 있고,
이를 이용해 원래 보내려고 했던 요청이 CORS 정책을 위반하는지 검증합니다.

브라우저의 개발자도구(F12)> 네트워크 탭을 확인해보면 동일한 요청이 2번 날아가는 것처럼 보입니다.

이때, 먼저 날아간 요청의 메소드를 확인해보면 OPTIONS인 것을 알 수 있는데요,
이 요청이 바로 ✨ preflight request입니다.

preflight request의 진행 순서

preflight request의 진행 순서를 그림으로 나타내면 아래와 같습니다.

1) Client → Server | 실제 요청에 사용할 메소드, 헤더를 Access-Control-Request-* 헤더에 담아 OPTIONS 요청을 보냅니다.

2) Server → Client | 허용되는 것들에 대한 정보를 헤더(Access-Control-Allow-*)에 담아 클라이언트에게 보냅니다.

3) Client | 응답 헤더를 검사 해 본 요청이 이루어질 수 있는지 파악합니다.

4) Client | 요청이 이루어질 수 없는 경우 CORS 에러를 발생시킵니다. 정상적인 경우 서버로 진짜 요청을 보냅니다.

(1-2 단계가 preflight request 단계입니다.)


preflight request 방식은
CORS 검증을 통과한 이후에 진짜 요청, 응답이 이루어집니다.



CORS 관련 헤더

CORS 검증에 사용되는 헤더를 정리하면 아래와 같습니다.


Request Headers

  • Access-Control-Request-Method: 본 요청에 사용할 메소드(Get, Post 등)

  • Access-Control-Request-Headers: 본 요청에 사용할 헤더

Response Headers

  • Access-Control-Allow-Origin: 허용되는 Origin(요청의 출처)

  • Access-Control-Allow-Methods: 허용되는 메소드

  • Access-Control-Allow-Headers: 허용되는 헤더

  • Access-Control-Max-Age: 해당 preflight request에 대한 응답이 브라우저에 캐시될 수 있는 기간(초)



CORS 위반한 경우

응답헤더가 아래와 같을 경우 브라우저는 해당 요청이 CORS 정책을 위반했다고 판단합니다.

CORS 정책 위반 🚨

  1. preflight 응답 헤더에 Access-Control-Allow-* 헤더가 존재하지 않는경우

  2. Access-Control-Allow-Headers에 Access-Control-Request-Headers가 하나라도 포함되지 않는경우

  3. Access-Control-Allow-Method와 Access-Control-Request-Method가 일치하지 않는 경우

  4. 현재 사이트(Origin)가 Access-Control-Allow-Origins에 포함되지 않는 경우






2) simple request

simple request?

이 방식은 preflight request 단계를 생략하고, 바로 (OPTIONS가 아닌)원래의 요청을 보내는 방식입니다.
보낸 요청에 대한 응답 헤더를 가지고 CORS 위반 여부를 검사합니다.
응답 헤더를 검사하는 로직은 preflight request 방식과 동일합니다.



simple request가 적용되는 상황

그럼,
특정 요청을 preflight request방식으로 처리할지, simple request방식으로 처리할지 판단하는 기준은 무엇일까요?

아래 조건을 모두 만족하면 브라우저는 해당 요청은 simple request 방식으로,
그렇지 않은 경우 preflight request로 처리합니다.

  • 요청의 메소드가 GET, POST, HEAD 중 하나

  • 요청의 헤더가 Accept, Accept-Language, Content-Language, Content-type, DPR, Downlink, Save-Data, Viewport-Width, Width

  • Content-Type 헤더가 application/x-www-form-urlencoded, multipart/form-data, text/plain 중 하나


simple request 주의사항!

simple request 방식은 일단 요청을 보내고 응답이 도착한 후에 해당 요청에 대한 CORS 위반 여부를 판단합니다.

보통은 CORS 에러가 발생하면 요청이 서버에 전달되지 않았다고 생각하는 경우가 많습니다.

그러나 simple request의 경우에는 정상적인 응답이 도착한 후에 검증이 이루어지므로, 서버에서는 해당 요청에 대한 로직을 수행하여 이미 데이터베이스나 다른 리소스들이 변경되었을 수도 있다는 점을 명심해야 합니다!







참고자료 🔗


profile
항상 새로운 것을 좋아하는 도파민 중독 개발자

0개의 댓글