CORS(Cross-origin Resource Sharing, 교차 출처 자원 공유)는 서로 다른 출처(origin) 간에 리소스를 공유할 수 있도록 하는 정책을 말한다. 이는 웹 브라우저 기반 보안 메커니즘으로 메인 origin을 방문하는 동안 다른 origin에 대한 요청을 허용하거나 거부할 수 있게 한다.
내가 만든 사이트에서 네이버 지도 API로 요청을 보낸다. (Cross-origin 요청)
크로스 origin 요청 시, 브라우저는 항상 origin 이라는 헤더를 요청에 추가한다.
브라우저는 요청에 origin이라는 헤더를 추가한다.
요청을 받은 네이버 지도 API 서버는 응답 헤더에 지정된 Access-Control-Allow-origin 정보를 실어서 보낸다.
브라우저는 2의 origin에서 보낸 출처값이 서버 응답 헤더에 담긴 Acess-Control-Allow-origin에 똑같이 있으면, 안전한 요청으로 간주하며 응답 데이터를 받아온다.
GET
, POST
, HEAD
를 사용한 요청Accept
/ Accept-Language
/ application/x-www-form-urlencoded
, multipart/form-data
, text/plain
인 Content-Type / Cache-Control
/ Content-Language
/ Content-Type
/ Expires
/ Last-Modified
/ Pragma
Access-Control-Allow-origin
: 서버는 요청 헤더에 있는 origin
을 검사하고, 요청을 받아들이기로 동의한 상태라면 특별한 헤더(Access-Control-Allow-origin
)를 응답에 추가한다.origin
에 값이 제대로 설정되어 전송되었는지 확인한다.Access-Control-Allow-origin
이 있는지 확인하여 서버가 크로스 origin 요청을 허용하는지 확인한다.Access-Control-Expose-Headers
: 자바스크립트 접근을 허용하는 안전하지 않은 헤더 목록이 담기며, 클라이언트가 다른 헤더에 접근할 수 있도록 하려면 서버는 이 헤더를 사용하여 헤더를 나열해야 한다. 사용자 지정 헤더를 추가로 표시하려면 여러 헤더를 콤마로 구분하여 지정할 수 있다.특별한 방법을 사용하지 않고도, <form>
이나 <script>
를 사용해 요청을 생성할 수 있다.
[출처: https://ko.javascript.info/fetch-crossorigin]
OPTIONS
메서드를 사용하고 두 헤더가 함께 들어가며 본문은 비어있다.Access-Control-Request-Method
: 안전하지 않은 요청에서 사용하는 메서드 정보를 담은 헤더Access-Control-Request-Headers
: 안전하지 않은 요청에서 사용하는 헤더 목록(여러 개일 경우 쉼표로 구분)을 담은 헤더Access-Control-Allow-origin
: 허용하는 originAccess-Control-Allow-Methods
: 허용된 메서드 정보Access-Control-Allow-Headers
: 허용된 헤더 목록Access-Control-Max-Age
: 퍼미션 체크 여부를 몇 초간 캐싱해 놓을 지를 명시하며, 브라우저는 일정 기간 동안 preflight 요청을 생략하고 안전하지 않은 요청을 보낼 수 있게 된다.자바스크립트로 크로스 origin 요청 시, 브라우저는 기본적으로 쿠키나 HTTP 인증과 같은 자격 증명을 함께 전송하지 않는다. 왜냐하면 그렇게 할 경우, 사용자 동의 없이 자바스크립트로 민감한 정보에 접근할 수 있게 되기 때문이다. HTTP 요청의 경우 대부분 쿠키와 함께 전송되지만, 자바스크립트를 사용해 만든 크로스 origin 요청은 그렇지 않다. 따라서 서버가 이를 허용하기 위해서는 자격 증명이 담긴 헤더를 명시적으로 허용하겠다는 세팅을 해야 한다.
클라이언트에서 credentials: "include"
옵션 추가 후 요청
fetch('http://another.com', {
credentials: "include"
});
서버에서 Access-Control-Allow-Credentials: true
헤더 추가 후 응답
200 OK
Access-Control-Allow-origin: https://javascript.info
Access-Control-Allow-Credentials: true
자격 증명이 함께 전송되는 요청을 보낼 땐 Access-Control-Allow-origin
에 *
을 쓸 수 없다. ⇒ 어떤 origin에서 요청이 왔는지에 대한 정보를 서버가 신뢰할 수 있다.
참고 자료