CORS에 대해서 제대로 정리를 해보자.
기본적으로 웹사이트 a는 웹사이트 b의 데이터를 가져오지 못한다. 그게 바로 Same-origin-policy라는 규칙이다. 웹 사이트 B가 '웹사이트 A는 내 데이터를 가져갈수 있다'고 허용할 수 있는데, 이걸 CORS(Cross-Origin Resource Sharing)라고 한다.
특정한 요청들은 CORS preflight를 요청하지 않는다.
그렇다면, 이 preflight이 뭔지 알아야할 것이다.
프리 플라이트는 본격적으로 요청을 보내기 전에 '사전확인'을 하는 것이다. 브라우저가 서버에 "이런 요청을 해도 될까?"라고 미리 물어보는 것이다.
주로 OPTIONS 요청이며,Access-Control-Request-Method, Origin, optionally Access-Control-Request-Headers. 이 헤더들을 사용한다.
이 요청은 브라우저단에서 자동으로 만들어지기 때문에 개발자들이 따로 조작을 할 필요는 없다. simple request들은 이러한 프리플라이트를 먼저 보내지 않는다.
simple request가 아니라면 이런식으로 프리플라이트 요청을 미리 보내는 것이다.
프리플라이트 요청은 동일한 url에서 만들어진 요청에 대해서 캐싱이 될 수 있는데, Access-Control-Max-Age 헤더를 사용한다.
simple request는 다음과 같은 조건들을 모두 만족해야 한다.
이 응답을 보면 Access-Control-Allow-Origin: *로 돼 있는데, 이는 모든 origin에서 리소스에 접근 가능하다는 뜻이다.
특정 origin으로 한정하고 싶다면 위와같은 헤더를 사용하면 된다.
프리플라이트가 오가는 과정을 한번 봐보자.
브라우저는 자바스크립트에서 사용하는 요청 파라미터를 보고서 프리플라이트가 필요한지를 판단한다. 이를 통해 서버는 해당 요청을 서버에서 수용가능한지를 판단하게 된다.
이렇게 프리플라이트에서는 두개의 헤더도 같이 가는데 Access-Control-Request-Method 헤더는 서버에게 실제 요청이 어떤 메서드인지를 알려주는 역할을 한다. The Access-Control-Request-Headers헤더는 요청이 어떠한 헤더들을 사용하는지 알려준다.
CORS 설정을 제한하지 않는다면, 악의적인 스크립트가 서버에 요청을 보내서 리소스에 마음대로 접근할 수 있다.
CORs is a feature built into browsers for added security. It prevents any random website from using your authenticated cookies to send an API request to your bank's website and do stuff like secretly withdraw money.
By default, browsers only allow api calls on the same .com or IP address. To expand the list, you need to set a specific header on your API to tell the browser which URLs are ok/safe. Usually a good start is to allow "http://localhost:*" during development
이런 상황을 생각해보자. 은행에 있는 인증과 관련된 쿠키를 외부 도메인이 가져가서 이를 활용하려고 한다.
SOP가 없다면, 외부 도메인이 쿠키를 사용해서 요청을 보내는 것을 막기가 쉽지 않다.
CORS로 정해진 도메인만 요청을 받도록 한다고 해보자. 외부 사이트에서 요청을 보냈을 때, 서버가 "어 우리 도메인이 아니네? 요청 거부" 라고 간단하게 처리할 수 있게 된다.
참고자료