작업을 하다가 CORS에러를 만나면 정말 당황스럽게 그지없다. 정말 CORS로 몇일을 밤새면서 에러를 해결해 본 경험은 개발자라면 누구나 있을법하다.
사실 아직도 엄청나게 이해되는 개념은 아니다. 그래도 언젠간 마주칠 CORS를 위해서 정리해놓고 대비를 하려고 한다.
CORS는 Cross-Origin Resource Sharing의 약자이다. 흔히 교차 출처 리소스 공유라고 한국말로 부르는데 저 단어마저도 어렵게 느껴진다. 밑에 자료는 MDN에서 말하는 CORS의 개념이다.
이에 대한 응답으로 서버는 Access-Control-Allow-Origin 헤더를 다시 보냅니다.
교차 출처 리소스 공유(Cross-Origin Resource Sharing, CORS)는 추가 HTTP 헤더를 사용하여, 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제입니다. 웹 애플리케이션은 리소스가 자신의 출처(도메인, 프로토콜, 포트)와 다를 때 교차 출처 HTTP 요청을 실행합니다.
출저: MDN
많은 웹 어플리케이션들이 이미지 파일이나 폰트, css 파일 같은 리소스들을 각각의 출처로부터 읽어온다. 만약에 웹 어플리케이션이 자기 자신이 속하지 않은 다른 도메인, 다른 프로토콜, 혹은 다른 포트에 있는 리소스를 요청하면 웹 어플리케이션은 cross-origin HTTP 요청을 실행한다.
만약에 프론트엔드 자바스크립트 코드가 https://www.naver.com 에서 https://www.naver.com/data.json 으로 json 데이터 요청을 보낸다면 이것이 바로 cross-origin HTTP 요청이 된다.
정리를해보면,
다른 도메인의 img파일이나 css파일을 가져오는 것은 모두 가능하다. 그러나 script로 감싸여진 부분에서 생성된 Cross-site HTTP Request는 Same-origin policy를 적용받아 Cross-site HTTP Request가 제한된다.
동일 출처로 요청을 보내는 것(Same-origin requests)은 항상 허용되지만 다른 출처로의 요청(Cross-origin requests)은 보안상의 이유로 제한된다는 뜻이다.
즉, 기존에는 보안상의 이유로 XMLHttpRequest가 자신과 동일한 도메인으로만 HTTP 요청을 보내도록 제한하였으나 웹 개발에서 다른 도메인으로의 요청이 꼭 필요하게 되었다.
그래서 XMLHttpRequest가 cross-domain을 요청할 수 있도록 CORS라는 것이 만들어졌다.
Origin이 CORS와 연관되어서 등장해서 정리해보려 한다.
Origin과 비슷한 개념으로 Domain이 있다.
이처럼 Origin과 Domain의 차이는 프로토콜과 포트번호의 포함 여부이다.
CORS를 공부하다면 굉장히 자주보는 단어가 바로 Preflight Request이다. 이 방식은 우리가 웹 어플리케이션을 개발할 때 많이 보는 시나리오이다. 이 경우에 해당하면 브라우저는 요청을 한번에 보내지 않고 예비 요청과 본 요청으로 나누어서 서버로 전송한다.
이 때, 브라우저가 본 요청을 보내기 전에 보내는 예비 요청을 Preflight라고 부르는 것이며, 이 예비 요청에는 HTTP메소드 중 OPIONS 메소드가 사용된다.
예비 요청의 역할은 본 요청을 보내기 전에 브라우저 스스로 이 요청을 보내는 것이 안전한지 확인하는 것이다.