교차 출처 리소스 공유(Cross-Origin Resource Sharing, CORS)는 브라우저가 추가 HTTP 헤더를 사용하여, 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제 - MDN
좀 더 쉽게 말하자면, 사용자가 지금 접속한 사이트와 다른 출처의 리소스를 사용하려 할 때 브라우저가 참고하는 화이트 리스트라고 할 수 있다. 만약, 이 리스트에 없다면 콘솔 창에 빨간 색 CORS 에러를 맞닥뜨리게 될 것이다.
그렇다면 왜 브라우저는 나를 막는 것일까? 나를 못 믿는 것인가? 아니다.
브라우저는 내가 방문한 사이트를 믿지 못하는 것이다. 브라우저는 우리가 웹 사이트를 이용할 때 굉장히 민감한 정보들을 저장하고 있다. 로그인 상태를 유지하기 위해 브라우저는 토큰 등의 정보를 쿠키로 저장하여 요청을 보낼 것이다.
이러한 인증 정보는 해커들의 타겟이 될 수 있다. 해커들은 정보를 빼내기 위해 사용자를 자신이 만든 사이트에 들어오게끔 유도한다. 만약, 사용자가 사이트에 접속한다면 브라우저에서 해커의 악성 코드가 실행되어 인증 정보를 탈취할 수도 있다. 즉, 내 의지와 상관없이 브라우저에 저장된 정보로 악의적인 행동을 취할 수 있다.
이러한 일들을 방지하기 위해서, 브라우저는 허용된 사이트 (CORS) 이외에 다른 사이트로의 요청이 갈 수 없게끔 사용자를 보호하고 있는 것이다. 엄밀히 말하자면, 요청을 막는 것은 동일 출처 정책 (Same-Origin Policy, SOP) 이 하고 있는 것이다.
원래 보안을 위해 다른 출처의 리소스를 접근하는 것이 불가능했지만, 웹 생태계가 다양해지면서 여러 서비스들끼리 자유롭게 데이터가 주고 받아질 필요가 생겼다. 그런데, 다른 사이트 간의 요청들을 브라우저가 막고 있기 때문에 이를 허용해주기 위해 어떠한 기준을 충족시키면 리소스를 공유할 수 있도록 만들어진 체제가 바로 CORS다.
CORS 동작의 시나리오는 다음 2가지로 나뉜다.
: 예비 요청을 보내지 않고, 서버에게 바로 본 요청을 전송한다. 이 후 서버가 응답 헤더에
Access-Control-Allow-Origin
과 같은 값을 보내주면 그때 브라우저가 CORS 정책 위반 여부를 검사하는 방식이다. GET이나 POST 등 일정 조건에 요청들에 대해 사용된다.
Origin
필드에 요청을 보내는 출처를 담아 전송한다.Access-Control-Allow-Origin
이라는 항목에 이 리소스를 접근하는 것이 허용된 출처를 명시해준다. 이후, 응답을 받은 브라우저는 자신이 보냈던 요청의 Origin과 서버가 보내준 응답의 Access-Control-Allow-Origin
을 비교한 후 이 응답 가능 여부를 결정한다.: 요청을 한번에 보내는 것이 아닌 예비 요청과 본 요청으로 나누어서 서버로 전송한다. 본 요청을 보내기 전 미리 예비로 보내는 요청을 Preflight
라고 하며, HTTP 메서드 중 OPTIONS
메서드를 사용한다. 서버는 예비 요청에 대한 응답으로, 어떤 요청을 허용하고 또 금지하는지에 대한 정보를 응답 헤더에 담아 보낸다. 예비 요청으로 본 요청이 안전한지 확인한 다음에야 본격적으로 요청을 보낼 수 있다. PUT이나 DELETE 등 서버 데이터에 영향을 줄 수 있는 요청들이기 때문에 먼저 요청의 허용 여부를 검증하는 것이다.
만약, 토큰 등 사용자 식별 정보가 담긴 요청에 대해서는 보다 엄격하다. 요청 옵션에 crendentials 항목을 true로 세팅해야 하고, 서버에서도 모든 출처를 허용하는 와일드카드 (*)가 아닌 요청 웹페이지의 주소를 정확히 명시한 다음 Access-Control-Allow-Credentials 항목을 true로 설정해주어야 한다.
참고 자료
교차 출처 리소스 공유 (CORS) - MDN
[Browser] CORS란? - Beomy
CORS란 무엇인가? - pilyeooong