blog-imgDucklog

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가 동작하는 과정

  1. 클라이언트에서 HTTP 요청의 헤더에 Origin을 담아서 전달함.

    • 웹은 HTTP 프로토콜을 이용하여 서버에 요청을 보냄
    • 이 때 브라우저는 요청 헤더에 origin 필드에 출처를 담아서 보냄
  2. 서버는 응답헤더에 Access-Control-Allow-Origin을 담아 클라이언트로 전달한다.

    • 이후 서버가 이 요청에 대한 응답을 할 때 응답 헤더에 Access-Control-Allow-Origin이라는 필드를 추가하고 값으로 '이 리소스를 접근하는 것이 허용된 출처 url'을 내려보낸다.
  3. 클라이언트에서 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: (특정 주소) 와 같이 출처를 명시해야한다!