CORS
CORS란?
크롬, 사파리 같은 브라우저에서 보안상의 이슈때문에 모든 웹 사이트는 같은 출처에 대한 데이터 요청은 허락하지만(SOP, 동일 출처 정책), 다른 출처로 데이터를 요청할 경우 특별한 규칙에 따라 허락을 받아야한다.
Cross Origin Resource Sharing
교차 출처 정보 공유에 대한 정책으로, 브라우저가 출처가 불분명한 응답을 막고 있는 것을 풀어주는 역할을 한다.
예시
내가 은행 사이트 서버에 요청을 보내서 은행 홈페이지에 로그인을 하였다. 그러면 브라우저 쿠키에 사용자의 인증정보 및 쿠키가 저장되어 있는데, 해커가 어떤 사이트 링크를 내게 보내서 내가 그 링크를 클릭하여 앞서 말한 인증 정보, 쿠키를 서버로 가져오는 Script 코드가 포함된 리소스를 응답으로 보내서 내가 만약에 그 응답을 받게 된다면, 해커가 나의 인증 정보와 쿠키를 가져갈 수 있게 된다.
이러한 보안상의 이슈를 방지하기 위해 브라우저가 동일한 출처의 요청이 아니라면 응답을 막아주는 것이다.
또한 쿠키를 못읽게 자바스크립트 코드로 만들어줘야한다.
즉, CORS는 다른 출처 간의 리소스를 공유할 수 있도록 하는 정책이다.
- 여기서 말하는 출처란, 보내고 받는 위치 즉, 웹 사이트랑 API 주소이다.
- 리소스는 주고 받는 데이터를 말한다.
내가 만든 사이트와 어떤 API라는 서로 다른 출처끼리 정보교환이 가능하려면 CORS 정책을 지켜야 한다는 말이다.
CORS 과정
요청을 받는 서버쪽에서 허락할 웹사이트를 미리 명시해줘야한다.
Simple Request (GET, POST 방식일 때 사용)
- 브라우저는 다른 출처끼리의 요청을 보낼 때에는 요청에 Origin 이라는 header를 추가한다.
1 | https://이주의사이트.com:5000 |
- Origin은 요청하는 쪽의 scheme, 도메인, 포트가 담겨있다.
- scheme은 요청할 자원에 접근할 방법(Http, FTP, telnet…) = 프로토콜
- https - scheme
- 이주의사이트.com - 도메인
- :5000 - 포트
요청을 받은 API 서버는 응답의 헤더에 지정된 ACAO(Access Control Allow Origin) 정보를 실어서 보낸다.
- ACAO 정보에는 미리 명시된 URL들이 들어가있다.
브라우저가 ACAO정보가 담긴 응답과 요청의 Origin을 비교하여 동일하면 허락해준다.
만약 동일하지 않아 허락못받으면 응답만 못받아온다. 빨간색 에러 발생
추가로 토큰과 같은 사용자 식별 정보가 담긴 요청에 대해서는 더 엄격한데 요청의 옵션에 credentials 항목을 true로 세팅해줘야하며, 받는 쪽에서도 아무 출처나 다 된다는 의미의 와일드 카드(*)가 아니라 보내는 쪽의 출처와 웹페이지 주소를 명확히 명시하고 Access Control Allow Credentials 항목을 true로 맞춰줘야 한다.
Preflighted (PUT, DELETE 방식일 때 사용)
Preflight 요청을 먼저 보내서 그에 대한 서버의 응답을 보고 안전한지 먼저 확인한다. 여기서 서버의 허락이 받아야지만 본 요청을 보낼 수 있다.
본 요청에 대한 과정은 심플리퀘스트와 동일하다.
- Origin, credentials, method 가 담긴 요청
⇒ 서버의 데이터에 영향을 줄 수 있는 요청이기 때문에 요청 보내기 전에 먼저 허용 여부를 검증해줘야 한다.