CORS

이재근·2022년 6월 14일
0

CORS(Cross Origin Resource Sharing)
CORS 정책은 우리가 가져오는 리소스들이 안전한지 검사하는 관문이다.

먼저 출처에 대해 잠깐 알고가자

출처 (Origin) 이란?
서버의 위치를 의미하는 https://google.comVisit Website 과 같은 URL은 하나의 문자열 같지만 다음과 같이 구성되어 있다.

이때 출처는 Protolcol 과 Host 그리고 Port까지 모두 합친 것을 의미한다.자바스크립트로 Location 객체가 가지고 있는 origin 프로퍼티에 접근하여 현재 출처를 알아낼 수도 있다.
EX)console.log(location.origin);

Cross Origin / Same Origin
웹에는 SOP(Same Origin Policy)와 CORS(Cross Origin Resurce Sharing) 두가지 정책이 있다.

SOP (Same-Origin Policy) <동일 출처 정책>
SOP는 "같은 출처에서만 리소스를 공유할 수 있다"라는 규칙을 가진 정책이다.

두개의 출처를 비교하는 방법은 URL의 구성요소 중 Protocol, Host, Port 이 세가지가 동일한지 확인하면 된다.
즉 같은 프로토콜, 호스트, 포트를 사용한다면 다른 요소는 다르더라도 같은 출처로 인정된다. 반대로 리소스가 자신의 출처와 다를경우 브라우저는 교차출처 요청을 실행한다.

출처를 비교하는 로직은 서버에 구현된 스펙이 아닌 브라우저에 구현된 스펙이다.
만약 CORS정책을 위반하는 요청에 서버가 정상적으로 응답을 하더라도 브라우저가 이 응답을 분석해서 CORS정책에 위반되면 그 응답은 처리하지 않게 된다.

요악하면 프로토콜, 포트, 호스트중 하나라도 일치하지 않으면 Cross Origin 이라고 한다.

CORS (Cross-Origin Resource Sharing) <교차&다른 출처 리소스 공유>

교차 출처 리소스 공유(Cross-Origin Resource Sharing, CORS)는,
추가 HTTP 헤더를 사용하여, 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제다.

시뻘겋게 CORS 어쩌구 에러는 CORS를 허용해서 아무런 탈 없이 다른 출처 리소스 공유를 해달라는 권고 사항 같은 것이라 볼 수 있다.

CORS 기본 동작과정
1. 클라이언트에서 HTTP요청의 헤더에 Origin을 담아 전달한다.
다른 Origin의 리소스 요청시 클라이언트는 HTTP요청을 보낸다.
이때 요청헤더의 Origin필드에는 요청을 보내는 Origin을 담아보낸다. 

  1. 서버는 응답헤더에 Access-Control-Allow-Origin을 담아 클라이언트로 전달한다.
    서버가 응답을 보낼때, 허락하는 Origin을 클라이언트에게 전달한다.

  2. 클라이언트에서, 자신이 보냈던 요청의 Origin과 서버가 보내준 Access-Control-Allow-Origin을 비교한다.
    자신이 보낸 Origin과 서버가 보내준 Access-Control-Allow-Origin을 비교하여 차단할지 말지를 결정한다.
    만약 유효하지 않다면 그 응답을 사용하지 않고 버린다.

  • 서버 응답은 CORS정책 위반 여부에 관여하지 않는다.CORS 정책에 의해 Origin을 비교하는 로직은 브라우저에 구현되어 있다.그래서 서버에서 정상적인 응답을 하여 상태코드가 200이 나오더라도,브라우저가 응답을 CORS정책 위반이라고 분석하면 그 응답은 사용하지 않는다. 브라우저가 CORS정책 위반을 분석하는 시간은 서버의 응답이 도착한 이후이다.즉, CORS정책을 위반하는 리소스 요청때문에 에러가 발생하더라도 서버 쪽 로그에서는 정상응답을 했다는 로그만 남기때문에, CORS를 정확히 이해해야만 CORS에러를 해결할 수 있는것이다.

CORS의 3가지 시나리오
위에서 소개한 방식은 CORS의 가장 기본적인 작동방식이고,
실제 CORS가 동작하는 방식은 3가지 시나리오에 따라 변경된다.

예비요청 (Preflight Request)
브라우저는 요청을 한번에 보내지 않고, 예비요청과 본요청으로 나누어 서버에 전달한다.

단순 요청 (Simple Request)
단순요청은 예비 요청(Prefilght)을 보내지 않고 바로 서버에 본 요청을 한 후,
서버가 이에 대한 응답의 헤더에 Access-Control-Allow-Origin과 같은 같을 보내주면 브라우저가 CORS정책 위반여부를 검사하는 방식이다.

인증된 요청 (Credentialed Request)
기존 예비요청에서 보안을 더 강화하고 싶을 때 사용한다.

CORS 해결방법 두가지 -

  1. Chrome 확장 프로그램 이용

  2. 서버에서 Access-Control-Allow-Origin 세팅하기

profile
하루 고생하면 코드가 나 대신 일해준다.

0개의 댓글