얼마전 프로젝트에서 서버를 통합하는 과정에서 API 요청을 보냈는데 CORS ERR 가 응답으로 떨어졌다.
그간 회사 프로젝트를 하면서 프론트단에서 API 요청을 보냈을 때 CORS ERR 을 마주한적이 한번도 없었고, 난생 처음보는 단어에 이게 뭐지? 라는 의문을 가졌고, 프론트 리더님과 백앤드 엔지니어 분들의 조율로 CORS ERR 는 해결이 되었다.
프론트 단에서 해당 에러를 처리하고자 변경된 것은 없지만, 웹 개발을 한다면 반드시 알아야 하는 개념으로써 MDN 을 통해 공부하고 내용을 정리해본다.
먼저 CORS (Cross Origin Resource Sharing) 에 대해서 알아보기 전에 동일 출처 정책에 대해서 살펴보자
동일 출처 정책이란 어떤 출처나 불러온 문서 혹은 스크립트가 다른 출처로부터 가져온 리소스와 상호작용 하는것을 제한하는 중요한 보안정책이다.
두 URL 의 프로토콜, 포트, 호스트가 같아야 동일한 출처라고 할 수 있다.
base: http://localhost:3000/home
case: https://localhost:3000/home (프로토콜이 다름으로 동일 출처가 아니다.)
case: http://localhost:3001/home (포트번호가 다름으로 동일 출처가 아니다.)
case: http://come.localhost:3000/home (호스트가 다름으로 동일 출처가 아니다.)
case: http://localhost:3000/page/application (경로만 다를 뿐이지 프로토콜, 포트, 호스트가 같기에 동일 출처이다.)
보안상의 이유로 브라우저는 동일 출처 정책을 고수한다. 만약 다른 출처에서 리소스를 불러오고 싶거나 다른 출처의 서버 데이터에 사이드 이펙트를 일으킬 수 있다면, 그 출처에서 올바른 CORS 헤더를 포함한 응답을 받아야한다.
위 캡쳐 화면을 보면 xhr 요청을 날리기 전 preflight (프리플라이트) 를 먼저 날린걸 확인할 수 있다. API 의 타겟이 다를 경우 (다른 출처) 먼저 프리플라이트를 날려 허용되는 요청인지를 체크받는다.
프리플라이트 요청이다. 요청 메서드는 OPTIONS 이며 응답 코드로는 200 OK 를 받았다.
Response Header 에는 위 사진의 헤더 외에 여러가지 헤더들이 더 있다. 이번에는 위 사진의 헤더들에 대해서만 알아보도록 하자.
위 헤더는 credentials 플래그가 true 일 경우 요청에 대한 응답을 표시할 수 있는지를 나타낸다. 이 헤더가 없으면 브라우저에서는 응답을 무시하고 웹 컨텐츠로 반환하지 않는다.
해당 헤더를 사용하면 브라우저가 접근할 수 있는 헤더를 서버의 화이트리스트에 추가할 수 있다.
리소스에 접근할 때 허용되는 메서드를 지정한다.
해당 헤더는 단일 출처를 지정하여 브라우저가 해당 출처의 리소스에 접근할 수 있도록 허용한다. 쉽게 말해서 해당 Remote 에 접근할 수 있는 출처를 나타낸다. 와일드 카드로 *
가 있을 수 있는데, *
는 모든 출처에서 해당 Remote 로 접근이 가능하다는 것을 의미한다.
프리플라이트를 보낼 때 실제 요청에서 어떤 헤더를 사용할 것인지 알려주는 헤더이다.
실제 요청에서 어떤 메서드의 요청을 보낼지 알려주는 헤더이다.
실제 요청을 보내는 오리진을 알려주는 헤더이다. (프리플라이트 request 의 출처이다.)
CORS 에러에 대해서 알아봤다. 프론트에서 CORS 에러에 대한 대처를 하지는 않았지만, 어떤 상황에서 CORS 에러가 날 수 있으며 어떤 해결책이 있는지 알아야 CORS 에러가 발생했을때 백앤드 엔지니어와 커뮤니케이션이 가능할 것 이라고 생각한다. 또한 항상 API 콜을 보낼 때 네트워크에서 OPTIONS 라는 독특한 메서드가 있어서 궁금했는데, CORS 에러에 대해서 공부하며 궁금증이 해결이 되었다.