Web

CORS(Cross-Origin Resource Sharing / 교차 출처 자원 공유)

Bonita SY 2020. 9. 23. 23:37
728x90
반응형

Same-Origin Policy

- 웹 어플리케이션의 중요 보안 모델

- 주로 스크립트로부터의 데이터 접근에 적용됨

- 일치하는 HTML 태그를 경유하는 이미지, CSS, 스크립트, 글꼴 등 출처를 경유하여 리소를 임베드하는 것은 제한되지 않음

 

출처 결정 규칙

 

CORS란?

- Cross-Origin Resource Sharing, 교차 출처 자원 공유

- 웹 페이지 상의 제한된 리소스를 최초 자원이 서비스된 도메인 밖의 다른 도메인으로부터 요청할 수 있게 하는 구조

- 추가 HTTP 헤더를 사용하여, 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제
- 웹 애플리케이션은 리소스가 자신의 출처(도메인, 프로토콜, 포트)와 다를 때 교차 출처 http 요청을 실행
- CORS 체제는 브라우저와 서버 간의 안전한 교차 출처 요청 및 데이터 전송을 지원
- 최신 브라우저는 XMLHttpRequest 또는 Fetch와 같은 API에서 CORS를 사용하여 교차 출처 HTTP 요청의 위험을 완화

 

CORS를 사용하는 요청(Request)

- XMLHttpRequest과 Fetch API
- 웹 폰트(CSS 내 @font-face에서 교차 도메인 폰트 사용 시, True type 폰트 사용 시)
- WebGL 텍스쳐
- drawImage()를 사용해 캔버스에 그린 이미지/비디오 프레임
- 이미지로부터 추출한 CSS Shapes

 

CORS 동작 방식

- 웹 브라우저에서 해당 정보를 읽는 것이 허용된 출처를 서버에서 설명할 수 있는 새로운 HTTP 헤더를 추가함으로써 동작

1. 서버 데이터에 사이드 이펙트를 일으킬 수 있는 HTTP 메소드(GET을 제외한 메소드: POST, PATCH, DELETE 등)에 대해, CORS 명센느 브라우저가 요청을 OPTIONS 메소드로 "preflight(사전전달)"하여 지원하는 메서드를 요청

2. 서버의 허가가 떨어지면 실제 요청을 보내도록 요구

3. 서버는 클라이언트에게 요청에 인증정보(쿠키, http 인증)를 함께 보내야 한다고 알려줄 수도 있음

- CORS 실패는 보안상의 이유로 상세정보 접근이 불가

-- 오직 오류가 발생했다는 사실만 알 수 있음

-- 상세 오류를 알아내려면 브라우저 콘솔 확인

 

교차 출처 요청의 예시

https://domain-a.com의 프론트 엔드 JavaScript 코드가 XMLHttpRequest를 사용하여 https://domain-b.com/data.json을 요청하는 경우

- 보안 상의 이유로, 브라우저는 스크립트에서 시작한 교차 출처 http 요청을 제한
※ XMLHttpRequest와 Fetch API는 동일 출처 정책을 따름
- 해당 API를 사용하는 웹 애플리케이션은 자신의 출처와 동일한 리소스만 불러올 수 있으며, 다른 출처의 리소스를 불러오려면 그 출처에서 올바른 CORS 헤더를 포함한 응답을 반환해야 함

 

 

 

CORS 관련한 HTTP 헤더

요청 헤더

- 서버를 호출할 때 설정

- cross-site XMLHTTPRequest 기능을 사용하는 개발자는 프로그래밍 방식으로 cross-origin 공유 요청 헤더 설정 필요 X

 

Origin

- cross-site 접근 요청 또는 preflight request의 출처를 나타냄

Origin: <origin>

- origin은 요청이 시작된 서버를 나타내는 URI 

- 경로 정보는 포함하지 않고, 오직 서버명만 포함

- null 또는 URL가 올 수 있음

- 접근 제어 요청에는 항상 Origin 헤더가 전송


Access-Control-Request-Method

- 실제 요청에서 어떤 HTTP 메서드를 사용할지 서버에게 알려주기 위해, preflight request 할 때 사용됨

Access-Control-Request-Method: <method>

Access-Control-Request-Headers

- 실제 요청에서 어떤 HTTP 헤더를 사용할지 서버에게 알려주기 위해, preflight request 할 때에 사용됨

Access-Control-Request-Headers: <field-name>[, <field-name>]*


응답 헤더

Access-Control-Allow-Origin

- 리턴된 리소스에는 다음 구문과 함께 하나의 Access-Control-Allow-Origin 헤더가 있을 수 있음

Access-Control-Allow-Origin: <origin> | *

- 단일 출처를 지정하여 브라우저가 해당 출처가 리소스에 접근하도록 허용

- 자격 증명이 없는 요청의 경우 "*" 와일드 카드는 브라우저의 origin에 상관없이 모든 리소스에 접근하도록 허용

Access-Control-Allow-Origin: https://mozilla.org

- 서버가 "*" 와일드카드 대신에 하나의 origin을 지정하는 경우, 서버는 Vary 응답 헤더에 Origin 을 포함

- 이 origin은 화이트 리스트의 일부로 요청 orgin에 따라 동적으로 변경될 수 있음

- 서버 응답이 Origin 요청 헤더에 따라 다르다는것을 클라이언트에 알려줌


Access-Control-Allow-Credentials

- 브라우저가 접근할 수 있는 헤더를 서버의 화이트리스트에 추가

Access-Control-Expose-Headers: <header-name>[, <header-name>]*

예제)
Access-Control-Expose-Headers: X-My-Custom-Header, X-Another-Custom-Header


Access-Control-Expose-Headers

- preflight request 요청 결과를 캐시할 수 있는 시간을 나타냄

Access-Control-Max-Age: <delta-seconds>

- delta-seconds 파라미터는 결과를 캐시할 수 있는 시간(초)를 나타냄


Access-Control-Max-Age

- credentials 플래그가 true일 때 요청에 대한 응답을 표시할 수 있는지를 나타냄

- preflight request에 대한 응답의 일부로 사용하는 경우, credentials을 사용하여 실제 요청을 수행할 수 있는지를 나타냄

- simple GET requests는 preflighted되지 않으므로 credentials이 있는 리소스를 요청하면, 이 헤더가 리소스와 함께 반환되지 않음

- 이 헤더가 없으면 브라우저에서 응답을 무시하고 웹 컨텐츠로 반환되지 않는다는 점!

Access-Control-Allow-Credentials: true


Access-Control-Allow-Methods

- 리소스에 접근할 때 허용되는 메서드를 지정

- 이 헤더는 preflight request에 대한 응답으로 사용됨

Access-Control-Allow-Methods: <method>[, <method>]*


Access-Control-Allow-Headers

- preflight request 에 대한 응답으로 사용

- 실제 요청시 사용할 수 있는 HTTP 헤더를 나타냄

Access-Control-Allow-Headers: <header-name>[, <header-name>]*

 

출처

https://ko.wikipedia.org/wiki/%EA%B5%90%EC%B0%A8_%EC%B6%9C%EC%B2%98_%EB%A6%AC%EC%86%8C%EC%8A%A4_%EA%B3%B5%EC%9C%A0

https://developer.mozilla.org/ko/docs/Web/HTTP/CORS

https://evan-moon.github.io/2020/05/21/about-cors/

https://ko.wikipedia.org/wiki/%EB%8F%99%EC%9D%BC-%EC%B6%9C%EC%B2%98_%EC%A0%95%EC%B1%85

728x90
반응형