CORS란?
CORS (Cross-Origin Resouce Sharing)
한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 특정 자원에 접근할 수 있도록 하는 것
예를 들어 abc.com 에서 def.com의 자원을 가져오려 할 때, 브라우저 측에서 이를 허용하는 것을 말한다.
CORS 에러
주로 프론트엔드에서 CORS 에러가 자주 발생한다.
포스트맨이나 백엔드에서 http로 요청을 보내면 되다가도, 크롬이나 사파리 같은 브라우저로 시도를 해보면 안 되는 경우가 그것이다.
브라우저 측에서 두 사이트 중 하나를 못 믿거나 둘 모두를 신뢰하지 못해서 데이터 전달을 막아놓은 것이다.
CORS 에러가 발생하는 이유
브라우저는 토큰과 같은 사용자 식별 정보를 가지고 있다. 그런데 다른 사이트와의 접근이 무제한일 경우, 해커들이 이 점을 악용해 위조된 페이지를 통한 요청(CSRF, Cross-Site Request Forgery)이나 악의적인 코드를 삽입(XXS, Cross-Site Scripting)하는 등의 방법으로 사용자의 정보를 탈취할 수 있다. 이를 방지하기 위해 다른 사이트로의 요청을 제한하는 정책이 생겼는데, 그것이 SOP(Same-Origin Policy)이다. SOP은 동일 출처, 즉 동일 URL끼리만 API 등의 데이터 접근이 가능하게 한 정책을 말한다.
CORS는 이런 SOP를 일시적으로 풀어주는 역할을 하는데, CORS 설정을 하지 않았을 경우 SOP에 의한 오류가 발생한다. 그리고 이런 에러는 보통 "$$@$.com has been blocked by CORS policy"라는 형태로 발생한다.
CORS 과정
브라우저는 다른 출처끼리의 통신이 있을 때는 요청에 Origin이라는 header를 포함한다.
요청하는 쪽의 header의 Origin 항목에는 요청하는 쪽의 scheme과 도메인, 포트가 담긴다.
scheme은 요청할 자원에 접근할 방법(http, ftp, telent) 등 프로토콜을 말한다.
요청을 받은 사이트는 답장 Header에 지정된 Access-Control-Allow-Origin 정보를 실어보낸다.
만약 요청한 쪽의 사이트가 CORS 옵션에 등록되어 있을 경우, 그 URL도 이 정보에 포함된다.
이후 브라우저에서 둘의 Origin 정보를 비교하고 요청하는 쪽과 답장을 보낸 쪽의 Header Origin이 같을 경우, 안전한 요청으로 간주하고 Response를 가져온다.
토큰 등 민감한 사용자 식별 정보를 가지고 있을 경우 과정은 보다 엄격해진다. 요청을 보내는 쪽에서는 credentials 항목을 true로 세팅해야 하고, 받는 쪽에서도 보내는 쪽의 URL을 정확히 명시하고 Access-Control-Allow-Origin을 true로 설정해야 한다.
CORS 종류
Simple Request
GET, POST 등의 요청에서 쓰이는 방법으로 별도의 사전절차 없이 바로 데이터 요청을 보내는 것을 말한다.
다음과 같은 조건을 충족시켜야 한다.
- 메서드는 GET POST HEAD 중 하나
- 헤더는 Accept, Accept-Language, Content-Language, Content-Type 만 허용
- Content-Type 헤더는 다음의 값들만 허용
- application/x-www-form-urlencoded
- multipart/form-data
- text/plain
Preflight Request
PUT, DELETE 등에서 사용되는 것으로, 본 요청을 보내기 전에 요청 자체를 승낙하는 프로세스이다. PUT, DELETE의 경우 서버의 데이터에 영향을 줄 수 있는 요청이기 때문에, 요청을 보내기 전에 먼저 요청에 대한 허용 여부를 결정하는 과정을 거친다. Options 메소드를 통해 Preflight Request 과정을 거친다.
Reference