CORS
추가 HTTP 헤더를 사용하여, 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제이다.
웹 애플리케이션은 리소스가 자신의 출처(호스, 프로토콜, 포트)와 다를 때 교차 출처 HTTP 요청을 실행한다.
출처란?
URL의 구성 요소인 프로토콜, 호스트, 포트를 말한다.
동일 출처 정책(Same Origin Policy)
다른 출처로부터 조회된 자원들의 읽기 접근을 막아 다른 출처 공격을 예방한다.
동일 출처(Same-Origin) 서버에 있는 리소스는 자유로이 가져올 수 있지만, 다른 출처(Cross-Origin) 서버에 있는 이미지나 유튜브 영상 같은 리소스는 상호작용이 불가능하다.
필요 이유
만일 제약이 없다면, 해커가 CSRF(Cross-Site Request Forgery)나 XSS(Cross-Site Scripting) 등의 방법을 이용해서 우리가 만든 애플리케이션에서 해커가 심어놓은 코드가 실행하여 개인 정보를 가로챌 수 있다.
출처 비교와 차단
출처를 비교하는 로직은 브라우저에 구현된 스펙.
교차 출처 리소스 공유(Cross-Origin Resource Sharing)
다른 출처의 리소스 공유에 대한 허용 / 비허용 정책이다.
CORS 정책을 허용하는 리소스에 한해 다른 출처라도 받아들일 수 있다.
CORS가 동작하는 원리
- 웹은 HTTP 프로토콜을 이용해 서버에 요청을 보낸다.
- 브라우저는 요청 헤더에 Origin이라는 필드에 출처를 함께 담아 보내게 된다.
- 서버는 응답헤더에 Access-Control-Allow-Origin을 담아 클라이언트로 전달한다.
- 이후 서버가 이 요청에 대한 응답을 할 때 응답 헤더에 Access-Control-Allow-Origin이라는 필드를 추가하고 값으로 리소스를 접근하는 것이 허용된 출처 url을 내려보낸다.
- 브라우저는 자신이 보냈던 요청의 Origin과 서버가 보내준 Access-Control-Allow-Origin을 비교해 본 후 차단할지 말지를 결정한다.
- 만약 유효하지 않다면 그 응답을 사용하지 않고 버린다(CORS 오류 발생)
출처 구분 기준
출처의 동일함은 두 URL의 구성 요소 중 Protocal(Scheme), Host, Port이 3가지만 동일하다면 동일 출처로 판단한다.
허용방법
각 사용하는 서버에서 응답 헤더에 Access-Control-Allow-Origin 필드에 허용할 출처를 등록해 준다.
예비 요청(Preflight Request)
브라우저는 요청을 보낼 때 한 번에 바로 보내지 않고, 먼저 예비 요청을 보내 서버와 잘 통신되는지 확인한 후 본 요청을 보낸다.
본 요청을 보내기 전에 브라우저 스스로 안전한 요청인지 미리 확인하는 것.
이때 브라우저가 예비 요청을 보내는 것을 Preflight라고 부르며, 이 예비요청의 HTTP 메서드를 GET이나 POST가 아닌 OPTIONS라는 요청이 사용된다.
문제점
실제 요청에 걸리는 시간이 늘어나게 되어 애플리케이션 성능에 영향을 미친다.
따라서 브라우저 캐시를 이용해 Access-Control-Max-Age 헤더에 캐시 될 시간을 명시해 주면, 이 Preflight 요청을 캐싱시켜 최적화가 가능하다.
단순 요청(Simple Request)
예비 요청을 생략하고 바로 서버에 직행으로 본 요청을 보낸 후, 서버가 이에 대한 응답 헤더에 Access-Control-Allow-Origin 헤더를 보내주면 브라우저가 CORS정책 위반 여부를 검사하는 방식
예비 요청 생략 기준
- 요청 메서드는 GET, HEAD, POST 중 하나여야 한다.
- Accept, Accept-Language, Content-Language, Content-Type, DPR, Downlink, Save-Data, Viewport-Width, Width 헤더여야 한다.
- Content-Type 헤더가 application/x-www-form-urlencoded, multipart/form-data, text/plain 중 하나여야 한다.
이 까다로운 조건들이 만족되어야 예비 요청은 생략된다.
그리고 생략되는 상황은 드물다 대부분 HTTP API 요청은 text/xml, application/json으로 통신하기 때문에 3번에 위배되기 때문이다.
인증된 요청
클라이언트에서 서버에게 자격 인증 정보를 실어 요청할 때 사용하는 요청이다.
세션 ID가 저장되어 있는 쿠키 혹은 Authorization 헤더에 설정하는 토큰 값등이 해당한다.
클라이언트에서 일반적인 JSON 데이터 외에도 쿠키 같은 인증 정보를 포함해서 다른 출처의 서버로 전달할 때 CORS의 세 가지 요청 중 하나인 인증된 요청으로 동작된다는 말이다.
인증 요청 방법
- 클라이언트에서 인증 정보를 보내도록 설정하기(credentials 옵션 설정)
- 서버에서 인증된 요청에 대한 헤더 설정하기
- 응답 헤더의 Access-Control-Allow-Credentials 항목 true
- 응답 헤더의 Access-Control-Allow-Origin 값에 와일드카드 문자 사용 불가
- 응답 헤더의 Access-Control-Allow-Methods 값에 와일드카드 문자 사용 불가
- 응답 헤더의 Access-Control-Allow-Headers 값에 와일드카드 문자 사용 불가
'Computer Science' 카테고리의 다른 글
HTTP METHOD (0) | 2023.03.22 |
---|---|
Rest API란? (0) | 2023.03.21 |