CORS란?
CORS란 무엇일까?
CORS(Cross-Origin-Resource-Sharing) 웹 개발을 하는 사람이라면 누구든지 CORS 에러를 만나본 경험이 있을 것이다.
CORS 에러가 발생하는 이유는, 웹 브라우저는 HTTP 요청에 대해서 어떤 요청을 하느냐에 따라서 다른 특징을 갖고 있기 때문이다. 자세한 내용은 아래에서 확인해보자.
요청 방식에 따른 CORS 발생
<img>,<video>,<script>,<link>
..etc
위 태그들은 기본적으로 교차 출처 정책을 지원한다. 그렇기 때문에 CORS 에러가 발생하지 않는다.
XMLHttpRequest, Fetch API
기본적으로 동일 출처 정책을 지원한다. API호출을 하거나 웹 폰트 적용을 할 때 CORS 에러를 만나는 경우가 많을 것이다.
자바스크립트는 서로 다른 도메인에 대한 요청을 보안상 제한한다. 브라우저는 기본적으로 하나의 서버 연결만 허용하도록 설정되어있다.
그렇다면, 우리는 왜 동일한 서버에서만 자원(데이터)를 접근할 수 있게 해놓을까?
동일 출처 정책이 필요한 이유
만약 서로 다른 출처를 갖고 있는 도메인이 서로에게 자유롭게 접근할 수 있는 환경은 좋지 않다. 해커가 CSRF나 XSS와 같은 방법을 이용하여 해킹을 한다면 우리의 개인 정보를 쉽게 가로챌 수 있다.
동일 출처와 다른 출처를 구분하는 기준
두 출처의 동일함은 URL의 구성요소 중 Protocol, Host, Port가 동일하다면 동일한 출처로 판단한다
만약 https://www.example.com:3000 라는 도메인이 있다고 하자.
https:// -> Protocol
www.example.com -> Host
:3000 -> Port
그래서 CORS가 뭔데?
CORS는 서로 다른 출처의 리소스 공유를 허용/비허용 해주는 정책이다.
개발을 하다보면 외부 API를 사용해야하는 경우도 있다. 그렇기 때문에 위와 같은 상황을 해결하기 위해서 CORS 정책이 있는 것이다.
CORS가 동작하는 과정
-
클라이언트에서 HTTP 요청의 헤더에 Origin을 담아서 전달함.
- 웹은 HTTP 프로토콜을 이용하여 서버에 요청을 보냄
- 이 때 브라우저는 요청 헤더에 origin 필드에 출처를 담아서 보냄
-
서버는 응답헤더에 Access-Control-Allow-Origin을 담아 클라이언트로 전달한다.
- 이후 서버가 이 요청에 대한 응답을 할 때 응답 헤더에 Access-Control-Allow-Origin이라는 필드를 추가하고 값으로 '이 리소스를 접근하는 것이 허용된 출처 url'을 내려보낸다.
-
클라이언트에서 Origin과 서버가 보내준 Access-Control-Allow-Origin을 비교한다.
-
이후 응답을 받은 브라우저는 자신이 보냈던 요청의 Origin과 서버가 보내준 응답의 Access-Control-Allow-Origin을 비교해본 후 차단할지 말지를 결정한다.
-
만약 유효하지 않다면 그 응답을 사용하지 않고 버린다. (CORS 에러 발생)
-
위의 경우에는 둘다 http://localhost:3000이기 때문에 유효하니 다른 출처의 리소스를 문제없이 가져오게 된다.
-
CORS 에러를 해결하는 방법
동작원리를 보면, 서버에서 Access-Control-Allow-Origin 헤더에 유효한 값을 포함하여 응답을 브라우저로 보내면 CORS 에러를 해결할 수 있다. 프론트단에서 CORS 에러를 발견했다면 서버에게 Access-Control-Allow-Origin에 유효한 값을 포함해서 달라고 요청해야 한다.
와일드 카드격인 * 를 사용하여 Access-Control-Allow-Origin에 헤더를 세팅하면 모든 출처에서 오는 요청을 받겠다는 의미이므로 당장은 편하겠지만 보안적으로 심각한 이슈가 발생할 수 있다.
그러니 Access-Control-Allow-Origin: (특정 주소) 와 같이 출처를 명시해야한다!