개인 공부를 위해 정리한 내용입니다. 수정이 필요한 내용 피드백주시면 감사하겠습니다 .🙂
웹 브라우저는 '같은 출처에서만 리소스를 공유할 수 있다'라는 규칙을 가지고 있다. 예를 들어 데이지 닷컴에서 Fetch API를 사용해서 크롱 닷컴 API URL로 GET 요청을 보낸다고 하자. 이때 크롱 닷컴에서 데이지 닷컴의 요청을 허용해 주는 작업을 하지 않았다면, 브라우저는 보안 상의 이유로 데이지 닷컴의 GET 요청을 제한한다.
✔️ 같은 출처: URL(https://www.daisy.com:80)의 구성 요소 중 Scheme(https://), Host(www.daisy.com), Port(:80) 일치
✔️ 리소스: 주고 받는 데이터
그냥 데이터를 조회해오는 것뿐인데 요청을 제한해야 하나라는 생각이 들 수도 있다. 하지만 악의적인 목적을 가진 사람이 네이버에 접속하려는 유저에게 가짜 URL을 전달하고, 유저가 그 가짜 URL로 가짜 네이버(짭이버)에 접속했다고 가정하자.
유저가 짭이버에 접속하게 되면 유저의 브라우저는 짭이버의 자바스크립트 파일을 받게 되는데 만일 그 자바스크립트 파일에 악의적인 코드가 있다면 유저의 브라우저에 저장되어 있는 인증 정보를 사용해서 진짜 유저인 것처럼 네이버 서버에 요청을 보내 유저의 개인 정보를 빼낼 수도 있을 것이다. 그렇기 때문에 브라우저의 기본 스펙이기도 한 SOP(Same-Origin Policy)는 브라우저 보안상 꼭! 필요한 존재이다.
그렇다면 웹에서는 항상 같은 도메인 간 HTTP 요청만 해야 할까? 만약에 다른 도메인의 자원을 사용하고 싶으면 어떻게 할까? 다른 도메인 즉 교차 도메인끼리도 자원을 공유할 수 있도록 해줘야 하지 않을까?
이때 필요한 개념이 CORS이다. CORS는 Cross-origin resource sharing의 약자이며, 말 그대로 웹 브라우저가 보안상의 이유로 장착하고있는 Same Origin Policy의 제약을 넘어 다른 도메인의 자원을 사용할 수 있도록 해주다는 것이다! 빨간 글씨로 C.O.R.S...👾적혀있어서 오류인줄만 알았는데 웹 개발자에게 꼭 필요한 존재였던 것이다! CORS 미워하지 마시길!
보안 상의 이유로, 브라우저는 스크립트에서 시작한 교차 출처 HTTP 요청을 제한합니다. 예를 들어, XMLHttpRequest와 Fetch API는 동일 출처 정책을 따릅니다. 즉, 이 API를 사용하는 웹 애플리케이션은 자신의 출처와 동일한 리소스만 불러올 수 있으며, 다른 출처의 리소스를 불러오려면 그 출처에서 올바른 CORS 헤더를 포함한 응답을 반환해야 합니다. MDN
그럼 CORS 통해 다른 출처의 리소스를 사용하고 싶다면 어떻게 해야할까? 가장 기본적인 방법은 아래처럼 HTTP 요청 시 클라이언트의 요청과 서버의 응답의 HTTP Header에 Access-Control-**
류의 정보를 주고 받는 것이다.
Access-Control-**
류의 HTTP Header를 서버에 보내야 하고, (출처표기)Access-Control-**
류의 HTTP Header를 클라이언트에 회신하게 되어 있어야 한다. (접근 허용 표기)하지만 이때 와일드카드인 *
을 사용하여 이 헤더를 세팅하게 되면 모든 출처에서 오는 요청을 받는다는 의미이기에 알 수 없는 출처에서 오는 요청까지 받을 수 있게 된다. 따라서 Access-Control-Allow-Origin:
에 출처를 명시해주는 것이 좋다.
CORS 관련 에러 메세지를 가장 많이 마주할 때는 바로 로컬에서 프론트엔드 개발을 할 때일 것이다. 물론 백엔드에는 배포 URL을 기준으로 Access-Control-Allow-Origin 헤더가 세팅되어있겠지만, 로컬에서 사용할 때는 localhost:3000 과 같은 범용적인 URL를 사용하게 되기 때문에 CORS 정책 위반 문제가 발생하기 쉽다. 이때는 프론트쪽에서 라이브러리에서 제공하는 프록시 기능을 사용해서 간단하게 CORS 정책을 우회할 수 있다.
//package.json
{
...,
"proxy": "http://localhost:8000",
...,
}
이렇게 설정을 해놓으면 HTTP 요청을 프록싱해주기 때문에 마치 CORS 정책을 지킨 것처럼 브라우저를 속이면서도 우리는 원하는 서버와 자유롭게 통신을 할 수 있다.
즉, 프록싱을 통해 CORS 정책을 우회할 수 있는 것이다. 하지만 이것도 결국 브라우저를 속여서 CORS 정책 문제를 해결한 경우이기 때문에 결론적으로는 백엔드에서 Access-Control-Allow-Origin 세팅을 해주는 게 더 안정적인 방법이다!
참고 자료
웹개발 짜증유발자! CORS가 뭔가요?
MDN CORS
CORS는 왜 이렇게 우리를 힘들게 하는걸까?
Cross Origin Resource Sharing - CORS