1. CORS란
교차 출처 리소스 공유(Cross-Origin Resource Sharing, CORS)는 추가 HTTP 헤더를 사용하여, 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제입니다. 웹 애플리케이션은 리소스가 자신의 출처(도메인, 프로토콜, 포트)와 다를 때 교차 출처 HTTP 요청을 실행합니다. - MDN-
Cross-Origin Resource Sharing의 약어이자 "교차 출처 리소스 공유"라는 의미로,
브라우저에서는 보안적 이유로 cross-origin HTTP 요청들을 제한한다.
cross-origin 요청을 하기 위해서는 서버의 허가가 필요한데, 서버에서 이를 동의하지 않으면 브라우저에서는 요청을 거절한다.
이러한 메커니즘(mechanism)을 CORS라고 한다.
따라서 CORS는 cross-origin 요청을 안전하게 처리 할 수 있는 메커니즘이다.
cross-origin (교차 출처)
자신의 출처(도메인, 프로토콜, 포트)와 다를 때를 의미
2. CORS의 필요성
- CORS가 없다면 어느 곳에서나 데이터를 요청 가능하게 되고, 타 사이트에서 표절을 하게 될 위험이 있다. 타 사이트에서 본 사이트와 동일하게 동작하도록 만들어 사용자를 속여 로그인하게 하고 정보를 탈취하여 유출할 수 있는 치명적인 위험 발생할 수도 있다.
CORS는 이러한 위험을 방지하도록 필요 시 서버와 협의하여 요청할 수 있게 한다.
3. CORS의 동작원리
3-1. Simple requests
HTTP method
- Accept
- Accept-Language
- Content-Language
Content-Type
- application/x-www-form-urlencoded
- multipart/form-data
- text/plain
위 조건을 만족하면 Simple requqets이다.
(추가적인 확인 없이 바로 요청을 보낸다.)
- 서버 요청
- 브라우저에서 요청한 Origin, 응답한 헤더 Access-Control-Request-Header 값 비교 후 응답
- 유효한 요청일 시, 리소스 응답
- 유효하지 않을 시, 브라우저에서 거절 및 에러 발생
3-2. preflight requests
Simple requests가 아닌 cross-origin 요청은 모두 preflight 요청. 요청을 보내는 것이 안전한지 확인하기 위해 먼저 OPTIONS 메소드를 사용하여 cross-origin HTTP 요청을 보낸다. 사용자 데이터에 영향을 미칠 수 있는 요청이기 때문에 사전확인 후 본 요청을 보낸다.
- Origin 헤더에 현재 요청하는 origin, Access-Control-Request-Method 헤더에 요청하는 HTTP method, Access-Control-Request-Headers 요청 시 사용할 헤더를 OPTIONS 메소드로 서버 요청 (헤더만 전송)
- 브라우저가 서버에서 응답한 헤더를 보고 유효한 요청인지 확인한다.
- 유효한 요청일 시, 리소스 응답
- 유효하지 않을 시, 브라우저에서 거절 및 에러 발생
요청 헤더 목록
- Origin
- Access-Control-Request-Method
- preflight 요청을 할 시, 어떤 메서드를 사용할 것인지 서버에게 알리기 위해 사용
- Access-Control-Request-Headers
- preflight 요청을 할 시, 어떤 header를 사용할 것인지 서버에게 알리기 위해 사용
응답 헤더 목록
- Access-Control-Allow-Origin
- 브라우저가 해당 origin이 자원에 접근할 수 있도록 허용
- " * "을 사용하면 credentials이 없는 요청에 한해서 모든 origin에서 접근이 가능하도록 허용
- Access-Control-Expose-Headers
- 브라우저가 액세스할 수 있는 서버 화이트리스트 헤더를 허용
- Access-Control-Max-Age
- preflight 요청이 얼마동안 캐싱 될 수 있는지를 나타냄
- Access-Control-Allow-Credentials
- Credentials가 true 일 때, 요청에 대한 응답이 노출될 수 있는지를 나타냄
- preflight 요청에 대한 응답의 일부로 사용되는 경우 실제 자격 증명을 사용하여 실제 요청을 수행할 수 있는지를 나타냄
- 간단한 GET 요청은 preflight 되지 않으므로 자격 증명이 있는 리소스를 요청하면 헤더가 리소스와 함께 반환되지 않으면 브라우저에서 응답을 무시하고 웹 콘텐츠로 반환하지 않음
- Access-Control-Allow-Methods
- preflight 요청에 대한 대한 응답으로 허용되는 메서드들을 나타냄
- Access-Control-Allow-Headers
- preflight요청에 대한 대한 응답으로 실제 요청 시 사용할 수 있는 HTTP 헤더를 나타냄