Protocol
, Host
, Port
를 통해 같은 출처인지 다른 출처인지 판단할 수 있다.
- 클라이언트가 페이스북에 로그인(토큰 발급)을 한다.
- 해커가 클라이언트에게
http://hacker.ck
라는 URL을 보냄.- 클라이언트가 해커가 보낸 링크가 흥미로워서 클릭함.
- 해커가 보낸 페이지에는 클라이언트의 토큰을 이용하여 개인정보를 탈취하는 스크립트가 포함되어 있음.
만약 페이스북 서버가 토큰만으로 사용자를 판단한다면 클라이언트와 해커의 요청을 구분하기 힘들 것이다. 그래서 개인정보를 탈취하여 악의적으로 사용 할 가능성이 있음
반면에 요청 URL을 확인한다면 클라이언트의 출처는 http://www.facebook.com/~ 이고 해커의 출처는 http://hacker.hc 일테니 서로 다른 출처라는 것을 확인하여 악의적인 요청을 방지할 수 있다.
위와 같은 상황, 요청의 출처가 다르다면 Cross Origin SOP에 위반이라고 한다.
하지만 외부 라이브러리도 사용해야 하는데 요청과 리소스를 매번 동일한 출처로만 받을 수는 없다.
이 때 필요한 것이 CORS이다.
CORS는 다른 출처의 자원을 공유하는 것이다.
교차 출처 리소스 공유(CORS)는 추가 HTTP 헤더를 사용하여, 한
출처
에서 실행 중인 웹 어플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록브라우저
에게 알려주는 체제이다.
출처 : MOZILLA
사전 요청 (Preflight Request)
단순 요청 (Simple Request)
인증 요청 (Credentialed Request)
사전 요청은 OPTIONS 메서드를 통해 다른 도메인 리소스에 요청이 가능한지 확인하는 작업이다.
요청이 가능한 것을 확인하면 실제 요청을 보낸다.
순서
Preflight Request
Preflight Response
특징
왜 필요할까?
Preflight가 왜 있는가에 대해서는 쉽게 말해서 CORS spec이 생기기 이전에 만들어진 서버들은 브라우저의 SOP(same origin policy) request만 가능하다는 가정하에 만들어졌는데, cross-site request가 CORS로 인해서 가능해졌기 떄문에 이런 서버들은 cross-site request에 대한 security mechanism이 없다보니 보안적으로 문제가 생길수 있으니 이런 서버들을 보호하기 위해 CORS spec에 preflight request를 포함한겁니다. Preflight request로 서버가 CORS를 인식하고 핸들할수있는지 먼저 확인을 함으로써 CORS를 인식하지 못하는 서버들을 보호할수있는 매커니즘 입니다.
Preflight 요청 없이 바로 요청을 보낸다.
단순 요청은 예비 요청을 보내지 않고 바로 서버에게 본 요청부터 때려박은 후, 서버가 이에 대한 응답의 헤더에 Access-Control-Allow-Origin
과 같은 값을 보내주면 그때 브라우저가 CORS 정책 위반 여부를 검사하는 방식이다. 즉, 프리플라이트와 단순 요청 시나리오는 전반적인 로직 자체는 같되, 예비 요청의 존재 유무만 다르다.
Simple Request는 아래와 같은 조건을 만족해야한다.
인증 관련 헤더를 포함할 때 사용하는 요청이다.
클라이언트
서버
만약 Credentials 옵션은 true로 줬는데 Access-Control-Allow-Origin의 값을 * 로 주면 에러가 발생합니다.