Today I Learned

[TIL] CORS에 대한 정리

mhko411 2021. 8. 3. 21:15
728x90

오늘은 React에서 API 서버에 데이터를 요청하였는데 CORS에 의해 데이터를 받을 수 없는 이슈가 발생했었다. 이전에도 Vue와 Django로 웹 개발을 진행할 때 두 개의 서버(View 서버, API 서버)를 모두 로컬 환경에서 켜놓고 프로젝트를 진행했었다. 초기에 CORS 때문에 요청한 데이터를 받지 못하는 이슈가 발생했었다. 하지만 그 당시에 정확한 개념을 파악하지 않았고 어떻게 해결해야 하는지만 급급했다.

따라서 이번 기회에 정확한 개념을 짚고 넘어갈 필요가 있었기 때문에 CORS가 무엇이고 왜 이러한 이슈가 발생하는지 알아보자.


먼저 CORS가 무엇인지 기본적인 개념을 보자.

CORS는 서로 다른 출처에서 리소스를 공유하는 것을 의미한다. 먼저 위와 같은 이슈가 발생한 원인은 서로 다른 출처 간의 리소스를 공유하기 때문에 이를 브라우저 측에서 차단한 것이다. 그렇다면 왜 브라우저는 이를 차단했을까? 그전에 출처에 대한 개념을 정확하게 이해할 필요가 있다.

 

출처란 무엇일까?

출처는 리소스의 위치가 된다. 즉, 서버에 존재하는 index.html의 주소가 출처가된다. 예를 들어 아래와 같은 URL이 있다고 해보자.

https://www.example.com:80

동일한 출처인지 아닌지를 판단할 때 Scheme, Host, Port를 확인한다. 즉 어떠한 프로토콜을 사용하는지, 서버의 주소, 포트 번호를 확인하는데 이 세개가 같을 때는 동일한 출처로 인정된다. 위의 URL과 같은 출처와 다른 출처의 예시를 보자.

https://www.example.com:80/dir/page2.html => 프로토콜, 호스트, 포트가 모두 동일하다.

https://www.example.com:90 => 프로토콜과 호스트는 같지만 포트가 다르기 때문에 동일한 출처가 아니다.

 

SOP (동일 출처 정책)와 CORS의 적용

웹에서는 서로 다른 출처에 대한 리소스 공유를 제한하는 정책이 두 개 존재한다. 첫 번째는 CORS이며 두 번째는 SOP이다. SOP는 동일한 출처에 한해서만 리소스를 공유할 수 있도록 한 것이다. 이때 로컬에서 View 서버와 API 서버를 모두 켜놓은 상태에서 로컬의 API 서버에 요청을 보낸다면 SOP 정책을 위반하게 된 것이다. 왜냐하면 서버들의 포트 번호가 다르기 때문이다. 그렇다면 동일한 출처에서만 리소스를 공유한다면 웹 생태계의 장점이 많이 사라지지 않을까?

 

따라서 CORS 정책을 통해 서로 다른 출처에서도 특정한 요청에 대해서는 리소스를 공유할 수 있도록 하였다. 클라이언트에서 서버에 데이터를 요청하면 서버에서는 요청을 받고 응답을 한다. 이때 중간의 브라우저에서 SOP 정책을 위반했기 때문에 클라이언트에 데이터를 보내지 않는다. 하지만 서버에서 특정 클라이언트(출처가 다른)가 보낸 요청에 대해서는 허락해주도록 설정한다. 

 

서버에서 서로 다른 출처이지만 리소스를 공유할 수 있는 클라이언트를 지정할 수 있다. 이렇게되면 브라우저에서는 다른 출처이지만 서버에서 허용했다는 것을 확인하고 클라이언트에게 데이터를 전달한다.


처음 프로젝트에서 CORS에 대한 이슈가 발생했을 때 로컬에서 데이터를 주고받기 때문에 안되는 것이라고 생각했지만 이번에 이러한 이슈가 또 발생하고 다른 사람들에게 이러한 이슈가 왜 발생하는지 설명하는데 정확하게 말할 수가 없었다. 다음에 이러한 이슈가 발생한다면 빠르게 대처할 수 있을 것 같다.