동일 출처 정책은 웹 브라우저에서 보안을 강화하기 위하여 동일한 출처에서만 리소스를 주고 받도록 하는 정책이다.
출처란 URL 주소이다. 동일한 출처가 정확히 똑같은 URL을 의미하는 것은 아니다.
URL 중에서도 프로토콜, 도메인 주소, 포트 번호가 같은 것을 의미한다.
이러한 동일 출처 정책이 있기 때문에 원래는 다른 출처에서 리소스를 받아오는 것이 제한된다.
하지만 다른 출처로부터 리소스를 받아오는 것은 필수 요소가 되었고, 이러한 문제를 해결하기 위해 나온 정책이 바로 Cors(교차 출처 자원 공유)이다.
직역하면 '교차 출처 리소스 공유'라는 뜻으로 동일한 출처가 아닌 다른 출처에서 데이터를 주고 받는 것을 허용하는 정책이다.
브라우저에서는 보안적인 이유로 cross-origin HTTP 요청들을 제한한다.
그래서 cross-origin 요청을 하려면 서버의 동의가 필요하다.
만약 서버가 동의한다면 브라우저에서는 요청을 허락하고, 동의하지 않는다면 브라우저에서 거절한다.
서버의 허락을 구하고 안전하게 요청할 수 있도록 하는 메커니즘을 Cors라고 부른다.
Cors 없이 모든 곳에서 데이터를 요청하게 된다면 악의적으로 정보를 추출하거나 다른 사람의 정보를 입력하는 등의 다양한 공격이 가능하다.
Cors는 이러한 공격에서 브라우저를 보호하고, 필요한 경우에만 서버와 협의하여 요청할 수 있도록 한다.
요청 방법은 요청하는 헤더와 응답하는 헤더 사이에서 이루어진다.
- Access-Control-Request-Method
- 요청을 할 때, 어떤 메서드를 사용할 것인지 알려준다.
- Access-Control-Request-Headers
- 요청을 할 때, 어떤 헤더를 사용할 것인지 알려준다.
- Access-Control-Allow-Origin
- 리소스에 접근할 수 있는지 허용여부를 알려준다.
- Access-Control-Expose-Headers
- 브라우저에게 접근할 수 있는 리스트를 알려준다.
- Access-Control-Max-Age
- 캐싱되는 시간을 알려준다.
- Access-Control-Allow-Credentials
- 크레덴셜이 True일 때, 요청할 것인지 알려준다.
- Access-Control-Allow-Methods
- 허용되는 메서드를 알려준다.
- Access-Control-Allow-Headers
- 사용 가능한 HTTP 헤더를 알려준다.
Cors가 안전하게 다른 출처 리소스를 공유할 수 있는 방법은 단순 요청 방법과 예비 요청 방법이 있다.
예비요청은 미리 요청을 보내보고, 안전한지 판단한 뒤에 본격적으로 요청을 진행하는 방식이다.
- 헤더에서 Access-Control-Request-Method를 통해 요청하는 HTTP 메서드(Get,Post,Put,Delete)를 보낸다.
- 헤더에서 Access-Control-Request-Headers를 통해 OPTIONS라는 헤더를 넣고 요청을 보낸다.
- 예비로 확인하는 절차이므로 바디에 아무것도 작성하지 않는다.
- 해당 메서드와 헤더가 유효하다면 서버는 응답 헤더를 통해 접근 가능여부, 사용가능한 리소스의 리스트, 캐싱시간 등을 알려준다.
유효하지 않다면 요청은 중단되고 에러가 발생한다.
단순 요청은 위의 예비 요청과는 달리 서버에 바로 본격적으로 요청을 시작한다.
미리 확인하지 않기 때문에 까다로운 조건들을 사용한다.
- Access-Control-Request-Method를 통해 요청할 때 메서드는 HTTP 메서드가 아닌 GET,HEAD,POST 중 하나여야 한다.
- Access-Control-Request-Headers 통해 요청을 보낼 때, Accept Accept-Language,Content-Language, Content-TypeDPR, Downlink, Save-Data, Viewport-Width 중 하나여야 한다.
- Content-Type을 사용할 경우 application/x-www-form-urlencoded, multipart/form-data, text/plain 중 하나여야 한다.
위와 같이 까다로운 조건을 걸고 해당 조건에 부합하다면 안전한 요청이라 인식하여 데이터를 응답하는 형식이다.