[Error] CORS(Cross-Origin Resource Sharing)
사전지식 - SOP(Same-Origin Policy)이란?
- mdn 설명 -
동일 출처 정책은 어떤 출처(프로토콜, 호스트, 포트)에서 불러온 문서나 스크립트가 다른 출처에서 가져온 리소스와 상호 작용할 수 있는 방법을 제한하는 중요한 보안 메커니즘입니다.
동일 출처 정책(Same-Origin Policy, SOP)은 웹 보안에 있어 중요한 원칙이지만, 모든 HTTP 요청에 적용되는 것은 아니다. SOP는 웹 페이지가 다른 도메인의 리소스에 접근하는 것을 제한하나, <img>, <link>, <script>와 같은 태그를 이용하여 다른 도메인의 이미지, CSS, JS 파일을 요청하는 것은 허용한다. 동일 출처 정책의 정확한 구현 명세는 없지만 최신의 브라우저들은 일정 규칙을 따르고 있다. ( RFC6454 )
CORS란?
- mdn 설명 -
교차 출처 리소스 공유(Cross-Origin Resource Sharing, CORS)는 추가 HTTP 헤더를 사용하여, 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제입니다. 웹 애플리케이션은 리소스가 자신의 출처(도메인, 프로토콜, 포트)와 다를 때 교차 출처 HTTP 요청을 실행합니다.
브라우저는 보안상 이유로 스크립트에서 시작한 교차출처 (corss-origin) 요청을 제한한다. 그래서 corss-origin 요청을 하려면 서버의 동의가 필요하고, 만약 서버가 동의하지 않는다면 브라우저에서 거절한다. (CORS Error)
이 문제를 해결할 수 있는게 'CORS(Cross-Origin- Resourece Sharing , 교차출처 리소스 공유)' 이다. 'CORS' 는 서로 다른 출처의 리소스에 접근할 수 있도록 하용하는 메커니즘 이며, 이를 위해 추가적인 HTTP-header 를 사용한다.
출처란?
출처(Origin)란 웹에서의 '출발지'를 의미한다. 웹에서는 문서나 파일이 위치한 곳을 나타내기 위해 프로토콜(예: HTTP, HTTPS), 호스트(도메인 이름), 포트(서비스를 제공하는 고유 번호)를 조합하여 출처를 정의한다.
해당 이미지의 구성 요소중에서 Protocol + Host + Port 가지가 같아여 동일출러 라고 한다.
CORS(교차 출처 리소스 공유)는 왜 필요한가?
웹 애플리케이션은 점점 더 상호 연결되고 복잡해지면서 다른 출처에서 제공하는 자원(예: 폰트, 이미지, API)을 활용할 필요성이 증가했다. 그러나, 보안을 위해 도입된 동일 출처 정책(SOP)은 기본적으로 한 출처에서 불러온 웹 페이지가 다른 출처의 자원과 상호 작용하는 것을 제한하는데, 이러한 제한은 웹의 개방성과 유연성을 저해할 수 있다. 따라서, 안전한 방식으로 다른 출처의 자원을 활용할 수 있게 해주는 메커니즘이 필요한데, 이것이 바로 CORS의 역할이다.
CORS 동작원리
CORS(Cross-Origin Resource Sharing)의 동작 원리를 세 가지 주요 정책에 따라 정리하면 다음과 같다.
단순 요청 (Simple Requests)
- 사용 메소드: GET, POST, HEAD
- 허용되는 헤더: Accept, Content-Type, Content-Language 등
- Content-Type 헤더: application/x-www-form-urlencoded, multipart/form-data, text/plain
- 동작 원리: 브라우저가 자동으로 Origin 헤더를 추가하여 서버로 보내고, 서버는 응답에 Access-Control-Allow-Origin 헤더를 포함하여 해당 출처의 요청을 허용할지 결정. 서버가 요청을 허용하면 요청이 성공적으로 처리되고,
서버가 이 헤더에 응답하지 않거나, 헤더 값이 출처와 일치하지 않는 도메인인 경우, 브라우저는 응답을 차단한다.
프리플라이트 요청 (Preflight Requests)
- 메소드: OPTIONS
- 목적: 실제 요청을 보내기 전에 안전한지 서버에 사전 체크를 요청.
- 요청 헤더 목록:
origin - 어디서 요청을 했는지 서버에 알려주는 주소
Access-Control-Allow-Method - 실제 요청이 보낼 HTTP 메서드
Access-Control-Allow-Headers - 실제 요청에 포함된 header - 응답 헤더 목록:
Access-Control-Allow-Origin - 서버가 허용하는 출처
Access-Control-Allow-Headers - 서버가 허용하는 header 리스트
Access-Control-Allow-Methods - 서버가 허용하는 HTTP 메서드 리스트
Access-Control-Max-Age- preflight 요청이 캐싱 될 수 있는지를 나타낸다. - 동작 원리: 브라우저는 OPTIONS 요청을 통해 서버에게 실제 요청에서 사용될 HTTP 메소드와 헤더를 서버에게 요청. 서버는 Access-Control-Allow-Methods, Access-Control-Allow-Headers, Access-Control-Allow-Origin 등의 헤더를 포함하여 응답, 해당 요청을 수행할 수 있는지 여부를 보내줌. 이를 통해 실제 요청이 안전하게 처리될 수 있는지 사전에 확인.
자격증명을 포함한 요청
- 사용 기술: XMLHttpRequest, Fetch API
- 특징: withCredentials 속성을 true로 설정하여 요청과 함께 사용자 자격증명(쿠키, HTTP 인증 등)을 포함시킬 수 있음.
- 서버 요구 사항: 서버는 Access-Control-Allow-Credentials 헤더에 true 값을 명시하여 자격증명을 포함한 요청을 허용해야 함. 또한, Access-Control-Allow-Origin 헤더에는 명확한 출처를 지정해야 하며, "*" 사용 불가.
Access-Control-Allow-Origin: "*" // 모든 출처에서의 요청을 허용
Access-Control-Allow-Origin:http://example1.com // 특정 도메인 요청 허용