브라우저 보안 정책인 CORS교차(다른) 출처 리소스 공유(Cross-Origin Resource Sharing, CORS)
는 서로 다른 오리진 간의 리소스를 공유하는 것이다. 웹 서버, 데이터베이스를 통해서 브라우저의 앱(웹 어플리케이션)의 사용자를 보호하기 위한 브라우저의 보안 장치이다.
한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제이다. 웹 애플리케이션은 리소스가 자신의 출처(도메인, 프로토콜, 포트)와 다를 때 교차 출처 HTTP 요청을 실행한다.
보안 상의 이유로 XMLHttpRequest와 Fetch API는 동일 출처 정책을 따른다. 즉, 이 API를 사용하는 웹 애플리케이션은 자신의 출처와 동일한 리소스만 불러올 수 있으며, 다른 출처의 리소스를 불러오려면 그 출처에서 올바른 CORS 헤더를 포함한 응답을 반환해야 한다.
서버의 위치를 의미하는 https://google.com/
과 같은 URL들은 마치 하나의 문자열 같아 보여도 사실은 여러 개의 구성 요소로 이루어져있다.
이때 출처는 Protocol
과 Host
,port
번호까지 모두 합친 것을 의미한다. 서버의 위치를 찾아가기 위해 필요한 가장 기본적인 것들을 합쳐놓은 것이다. 출처 내의 포트 번호는 생략이 가능한데 이는 각 웹에서 사용하는 HTTP
, HTTPS
프로토콜의 기본 포트 번호가 정해져있기 때문이다.
그러나 만약 https://google.com:443
과 같이 출처에 포트 번호가 명시적으로 포함되어 있다면 이 포트 번호까지 모두 일치해야 같은 출처라고 인정된다.
SOP는 “같은 출처에서만 리소스를 공유할 수 있다”라는 규칙을 가진 정책이다. 브라우저는 보안을 위해서 SOP를 만들었다. ex) XMLHttpRequest와 Fetch API
그러나 웹이라는 오픈스페이스 환경에서 다른 출처에 있는 리소스를 가져와서 사용하는 일은 굉장히 흔한 일이기 때문에 몇 가지 예외 조항을 두고 이 조항에 해당하는 리소스 요청은 출처가 다르더라도 허용하기로 했는데, 그 중 하나가 “CORS 정책을 지킨 리소스 요청”이다.
브라우저의 개발자 도구를 열면 DOM이 어떻게 작성되어있는지, 어떤 서버와 통신하는지, 리소스의 출처는 어디인지와 같은 각종 정보들을 알 수 있다. 때문에 웹에서 돌아가는 클라이언트 어플리케이션은 사용자의 공격에 취약하다. 이런 상황 속에서 다른 출처의 어플리케이션이 서로 통신하는 것에 대해 아무런 제약도 존재하지 않는다면 악의를 가진 누군가가 사용자의 정보를 탈취하기가 쉬워지고 사용자가 악성 사이트로 접속할 수도 있다.
URL의 구성 요소 중 Scheme, Host, Port만 동일하면 된다.
어떤 방법을 통해 서로 다른 출처를 가진 리소스를 안전하게 사용할 수 있을까?
기본적으로 웹 클라이언트 어플리케이션이 다른 출처의 리소스를 요청할 때는 HTTP 프로토콜을 사용하여 요청을 보내게 되는데, 크로스 오리진 요청을 보낼 경우 브라우저는 항상 Origin(필드에 요청을 보내는 출처)을 헤더를 요청에 추가한다.
https://google.com/어쩌구
에서 https://anywhere.com/request
에 요청을 보낸다고 가정해 보자. 헤더는 다음과 같은 형태가 된다.
GET /request
Host: anywhere.com
Origin: https://google.com/
...
브라우저는 요청을 한번에 보내지 않고 예비 요청과 본 요청으로 나누어서 서버로 전송한다.
이때 브라우저가 본 요청을 보내기 전에 보내는 예비 요청을 Preflight(미리 전송)라고 부르는 것이며, OPTIONS 메서드를 통해 다른 도메인의 리소스로 HTTP 요청을 보내 실제 요청이 전송하기에 안전한지 확인한다.
선생님 저도 js, 리액트 해야하는데 포스트보니까 왤케 하기가싫ㅈㅕ... 딱봐도 넘나 어려워보이는것