CORS( Cross-Origin Resource Sharing )란?
- CORS( Cross-Origin Resource Sharing )는 추가 HTTP 헤더를 사용하여 다른 출처와 자원을 공유할 수 있도록 브라우저에게 알려주는 정책입니다. CORS 동작 방식에 따라서 Preflight Request, Simple Request, Credential Request로 나뉩니다. 이러한 정책이 필요한 이유는 브라우저의 SOP( Same-Origin Policy ) 보안 때문이며, SOP는 아래에서 설명하겠습니다.
출처( Origin )란?
- 출처( Origin )란 위 URI 구성에 나와있듯이 Protocol, Host, Port를 묶어서 표현한 것을 의미합니다.
SOP( Same-Origin Policy )
- 현재 출처와 다른 출처( Origin )와의 리소스를 공유하는 것을 제한하는 정책입니다.
SOP가 필요한 이유
- SOP(Same-Origin Policy)가 필요한 대표적인 이유로는 XSS(Cross-Site Scripting) 공격이 있습니다. XSS는 해커가 서버에 악의적인 스크립트를 심어서 사용자가 이를 조회했을 때 해커가 작성한 스크립트를 실행하여 자신의 세션 정보와 같이 중요한 정보가 해커의 서버로 송신되는 상황을 방지하기 위함입니다.
SOP는 동일한 Origin을 대상으로만 Request를 허용하기 때문에 위와같이 사용자가 해커가 심어놓은 스크립트를 실행한다 하더라도 사용자의 정보가 다른 Origin으로 탈취되는 상황을 방지할 수 있습니다.
CORS가 필요한 이유
- 모든 요청을 동일한 서버에 한다면 CORS는 필요하지 않습니다. 하지만, 아래와 같은 이유로 CORS를 이용하여 다른 출처로 요청하여 리소스를 공유하는 상황이 생길 수 있습니다.
프론트와 백엔드의 서버 분리
- 현대 웹 애플리케이션는 빠른 서비스를 위해 서버가 크게 프론트와 백엔드로 나누어졌습니다. 클라이언트 측에서 요청을 하는 순간 프론트 서버의 응답을 받아 랜더링이 되고, 데이터는 백엔드 서버에 요청하여 받아오게 되는 흐름은 다른 출처간의 리소스 공유를 막는 SOP 때문에 처리의 한계를 가졌습니다.
다른 출처의 데이터 사용
- 웹 구현시 REST API를 통해 다른 출처의 데이터를 요청해 리소스를 공유하는 경우가 많아졌습니다.
마이크로 서비스 아키텍쳐
- 트래픽양이 증가하면서 서버 한대로는 물리적으로 버티기 힘들어졌고 여러개 서버의 필요성이 대두되었습니다. 예를들어서 A 서버는 로그인 처리를 위한 서버, B 서버는 주문만 받는 서버처럼 하나의 서버가 특정 기능만을 수행하도록 분할하여 관리할 수 있습니다.
Preflight Request
- 기본적으로 브라우저는 요청을 보낼 때 바로 보내지 않고, 먼저 Preflight Request를 보내 서버와 잘 통신되는지 확인 후 본 요청을 보냅니다. Preflight Request를 보낼 때 HTTP 메소드를 OPTIONS로 하여 요청합니다.
Prefligh Request를 이용한 통신 과정
1. 자바스크립트의 fetch()
메서드를 통해 리소스를 요청합니다.
2. 브라우저는 서버로 OPTIONS 메서드로 Preflight Request를 보냅니다.
- Origin 헤더에 자신의 출처를 넣습니다.
- Access-Control-Request-Method 헤더에 실제 요청에 사용할 메소드를 설정합니다.
- Access-Control-Request-Headers 헤더에 실제 요청에 사용할 헤더들을 설정합니다.
3. Preflight Request를 받은 서버는 어떤 것을 허용하는지에 대한 정보를 헤더에 담아 응답합니다.
- Access-Control-Allow-Origin 헤더에 허용되는 Origin을 설정합니다.
- Access-Control-Allow-Methods 헤더에 허용되는 메소드들의 목록을 설정합니다.
- Access-Control-Allow-Headers 헤더에 허용되는 헤더들의 목록을 설정합니다.
- Access-Control-Max-Age 헤더에 해당 예비 요청이 브라우저에 캐시될 수 있는 시간을 초 단위로 설정합니다.
4. 응답받은 브라우저는 헤더를 확인하여 해당 요청이 안전한지 확인하고 본 요청을 보냅니다.
5. 이후 요청에는 Access-Control-Max-Age에 설정된 시간만큼 캐시하여 Preflight Request를 생략합니다.
Simple Request
- Simple Request는 메서드와 헤더 정보들을 확인하여 보안적으로 안전한 요청이라면 Preflight Request를 생략하고 바로 서버에 본 요청을 하는 방식입니다.
이 요청을 받은 서버는 응답 헤더에 Access-Control-Allow 헤더들을 설정하여 응답하면 브라우저가 CORS 정책 위반 여부를 검사합니다. 즉, 조건에 맞다면 Preflight Request를 생략하고 응답 데이터의 Access-Control-Allow 헤더들이 올바른지 확인하여 응답 거부 여부를 결정합니다.
Simple Request를 이용한 통신 과정
- Simple Request는 아래 3가지 조건을 충족할 때만 Reflight Request를 생략하여 이루어지며, 아래와 같이 까다로운 조건 때문에 Simple Request가 되는 경우가 상당히 드뭅니다.
Simple Request 4 가지 조건
- 요청의 메소드는 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만 허용합니다.
- 클라이언트가 credentials 옵션을 설정하지 않아야 합니다. (즉, 자격 증명 정보를 서버로 전송하지 않아야 합니다.)
Credential Request
- 인증된 요청은 클라이언트에서 서버에게 자격 인증 정보( Credential )를 실어 요청하는 것을 말합니다. 여기서 말하는 자격 인증 정보란 쿠키에 저장되어 있는 SessionID 또는 Authorization 헤더에 설정하는 JWT와 같은 Token 값 등을 말합니다. 이러한 인증된 요청을 다른 출처로 요청할 때에는 서버는 Access-Control-Allow 헤더에 더 구체적인 응답이 필요합니다.
인증된 요청을 하는 방법
same-origin(기본값) | 같은 출처간의 요청에만 인증 정보를 담음 |
include | 모든 요청에 인증 정보를 담음 |
omit | 모든 요청에 인증 정보를 담지 않음 |
credentials 설정
fetch("https://example.com:8888", {
method: "POST",
credentials: "include",
body: JSON.stringify({
name: "devhun",
}),
});
인증된 요청에 대한 서버 응답 방법
- 서버도 마찬가지로 인증된 요청에 대해서는 일반적인 CORS 요청과는 다르게 처리해야합니다. 응답 헤더를 아래와 같이 설정하지 않는다면 응답 받은 브라우저는 CORS 정책에 의해 요청이 거부됩니다.
응답 헤더 설정
- 응답 헤더의 Access-Control-Allow-Credentials 항목을 true로 설정해야 합니다.
- 응답 헤더의 Access-Control-Allow-Origin의 값에 와일드 카드("*")는 사용할 수 없습니다.
- 응답 헤더의 Access-Control-Allow-Methods의 값에 와일드 카드("*")는 사용할 수 없습니다.
- 응답 헤더의 Access-Control-Allow-Headers의 값에 와일드 카드("*")는 사용할 수 없습니다.
'네트워크 > HTTP' 카테고리의 다른 글
Web Server와 WAS(Web Application Server)의 차이점 (0) | 2023.02.26 |
---|---|
Cookie, Session, JWT( JSON Web Token )란? (0) | 2023.02.21 |
HTTP 헤더의 종류와 사용법 (0) | 2023.01.30 |
HTTP 상태코드란? (0) | 2023.01.29 |
HTTP API 설계 방법과 HTTP 메서드와 특징 (1) | 2023.01.29 |