[Network] 교차 출처 리소스 공유 : CORS(Cross Origin Resource Sharing) 이해하기
adjh54
2024. 10. 26. 15:59
해당 글에서는 교차 출처 리소스 공유 : CORS(Cross Origin Resource Sharing)에 대해 이해를 돕기 위해 작성한 글입니다.
1) 교차 출처 리소스 공유 : CORS(Cross Origin Resource Sharing)
💡 교차 출처 리소스 공유 (CORS: Cross-Origin Resource Sharing)
- 브라우저가 자신의 출처(Same Origin)가 아닌 ‘다른 어떤 출처(Cross Origin)’로부터 자원을 요청하는 것에 대해 허용하도록 서버가 이를 허가해 주는 HTTP 헤더 기반 메커니즘을 의미합니다. - 서버가 실제 요청을 허가할 것인지 확인하기 위해 브라우저가 보내는 ‘사전 요청(프리플라이트, Preflight)’ 메커니즘에 의존합니다. 이 사전 요청을 통해 브라우저는 실제 요청에서 사용할 HTTP 메서드와 헤더에 대한 정보가 표시된 헤더에 담아 보냅니다.
[더 알아보기] 💡 출처(Origin)
- 웹 페이지나 리소스의 출처를 나타냅니다. 일반적으로 프로토콜(http/https), 도메인, 포트 조합으로 구성이 됩니다. - 예를 들어서 https://example.com:443를 의미합니다. https 프로토콜을 이용하며 example.com의 도메인을 가지며, 기본 포트인 443 포트를 가집니다.
1. 동일한 출처(Same Origin)와 다른 출처(Cross Origin)
💡동일한 출처(Same Origin)와 다른 출처(Cross Origin)
💡 동일한 출처(Same Origin)
- domain-a.com이라는 웹 브라우저와 domain-a.com이라는 웹 서버는 동일한 출처(Origin)를 가지고 있습니다.
1. 웹 브라우저에서는 [GET] /index.html 페이지를 웹 서버로 요청을 합니다. - 해당 페이지에는 styles.css, header.png 파일이 포함되어 있어 함께 요청이 됩니다.
2. 웹 서버에서는 동일한 출처(Same-origin) 임을 판단하여 리소스 접근에 대한 요청을 수락(allow)하여 페이지와 이미지를 제공합니다.
💡 다른 출처(Cross Origin)
- domain-b.com이라는 웹 브라우저와 domain-a.com이라는 웹 서버는 서로 다른 출처(Origin)를 가지고 있습니다.
1. 웹 브라우저에서는 [GET] img.png 파일을 웹 서버에 요청합니다.
2. 웹 브라우저에서는 동일한 출처(Same-Origin)가 아님이 판단되어서 CORS 오류를 웹 브라우저에게 반환합니다. - 해당 상황에서 CORS를 허용하였다면 서로 다른 출처(Origin)에서도 제공을 해줄 수 있습니다.
- 웹 보안의 중요한 개념으로 동일 출처 정책을 의미합니다. 이는 웹 브라우저가 다른 출처의 리소스에 접근하는 것을 제한하는 보안 메커니즘을 의미합니다. - 이는 웹 애플리케이션의 보안을 강화하지만 때로는 합법적인 크로스 요청을 방해할 수 있어 CORS가 필요하게 됩니다.
2.1. SOP(Same-Orgin Policy) 정책 특징
💡SOP(Same-Orgin Policy) 정책 특징
특징
설명
동일 출처 요구
웹 페이지와 그 페이지가 요청하는 리소스의 출처가 같아야 합니다.
출처의 정의
프로토콜(http/https), 도메인, 포트가 모두 동일해야 동일 출처로 간주됩니다.
보안 강화
악의적인 스크립트가 다른 웹사이트의 데이터에 무단으로 접근하는 것을 방지합니다.
제한 완화
CORS(Cross-Origin Resource Sharing)를 통해 필요한 경우 이 정책을 완화할 수 있습니다.
2.2. 동일한 출처와 서로 다른 출처 비교
💡동일한 출처와 서로 다른 출처 비교
- 기준이 되는 “http://example.com”일 경우 동일한 출처로 간주되는 경우와 서로 다른 출처로 간주되는 경우에 대해 알아봅니다.
# 기준 도메인<http://example.com># 동일한 출처로 간주되는 경우 <https://example.com:443/page1><https://example.com:443/page2># 서로 다른 출처로 간주되는 경우 <https://example.com># 프로토콜(HTTP, HTTPS)이 다른 경우 <https://example.com:8080># 포트 번호가 다른 경우(기본 443 vs 8080)<https://sub.example.com># 호스트(도메인)이 다른 경우
3. CORS 사용 목적
목적
설명
보안 강화
악의적인 웹사이트로부터 사용자 데이터를 보호합니다.
리소스 공유 허용
필요한 경우 다른 출처의 리소스에 접근할 수 있도록 합니다.
API 접근 제어
서버가 허용한 클라이언트만 API에 접근할 수 있도록 합니다.
마이크로서비스 아키텍처 지원
서로 다른 도메인에서 실행되는 서비스 간 통신을 가능하게 합니다.
개발 환경 지원
로컬 개발 환경과 실제 서버 간의 통신을 허용합니다.
2) 예비 요청 : 프리플라이트(Preflight)
💡예비 요청 : 프리플라이트(Preflight)
- 프리플라이트 요청은 CORS 메커니즘의 일부로, 실제 요청을 보내기 전에 브라우저가 서버에 보내는 예비 요청입니다. - 이는 브라우저가 서버의 CORS 정책을 확인하고, 실제 요청이 안전한지 확인하는 과정입니다.
1. 예비 요청과 실제 요청
💡 예비 요청과 실제 요청
- 예비 요청은 CORS 정책을 확인하기 위한 사전 단계로, 실제 요청의 안정성을 보장하며, 실제 요청은 원하는 데이터를 요청하고 처리하는 단계입니다. - 실제 요청의 경우는 HTTP Method 중 OPTIONS 메서드를 사용하지만, 실제 요청의 경우는 다양한 HTTP 메서드를 사용할 수 있습니다.
- 해당 프리플라이트는 특정 리소스에 접근할 때 수행이 되며, 처음 호출되는 출처(origin)에 대해서 수행이 됩니다. - 예를 들어서, /api/v1/user/user라는 엔드포인트로 호출이 되었을 때, 한번 수행되고 동일한 엔드포인트에 대해서는 캐싱 기간이 만료되지 않고는 프리플라이트가 수행되지 않으며, 다른 엔드포인트로 호출하는 경우에는 프리플라이트가 수행이 됩니다.
1. 클라이언트 → 브라우저 - 클라이언트에서는 특정 동작에 대해서 이에 대한 처리를 위해 실제 요청을 합니다.
2. 브라우저 → 서버 ( 출처가 확인되기 전에 한 번만 수행) - 브라우저에서는 Preflight Request를 통해서 출처(origin)를 서버에 알리고 있습니다. - 이 과정에서 HTTP METHOD OPTIONS로 프리플라이트 요청을 보냅니다.
3. 서버 → 브라우저 ( 출처가 확인되기 전에 한 번만 수행) - 서버는 브라우저에 대해 사전에 요청을 통해 출처(origin)를 확인하고 이에 대한 접근 허용 응답 헤더(Access-Control-Allow-Origin)를 제공합니다
4. 브라우저 → 서버 - 브라우저는 최초 Preflight 과정을 거쳐서 실제 요청을 수행합니다.
5. 서버 → 브라우저 → 클라이언트 - 해당 과정을 마친 경우 이에 대한 응답을 클라이언트에게 제공합니다.
https://leekoby.github.io/posts/cors/
3) Chrome 브라우저를 통한 CORS 처리 확인
1. 최초 프리플라이트(Preflight) 수행
💡 최초 프리플라이트(Preflight) 수행
- 아래와 같이 브라우저에서 웹 서버로 특정 origin에 API 요청이 발생하는 경우 preflight가 발생합니다.
2. 프리플라이트(Preflight) 내용 확인
💡프리플라이트(Preflight) 내용 확인
- 해당 과정을 통해서 Request Method는 OPTIONS로 전달이 되었고, 응답으로는 접근 허용 응답 헤더(Access-Control-Allow-Origin)가 http://localhost:3000 임을 확인하였습니다.
3. 프리플라이트(Preflight) 수행 빈도 확인
💡 프리플라이트(Preflight) 수행 빈도 확인 -1 - api/v1/user/user로 동일한 서버 요청 시, 최초 한 번에 preflight가 수행이 되며, 이후 동일한 엔드포인트로 호출을 하는 경우에는 수행이 안됨을 보여주고 있습니다.
💡 프리플라이트(Preflight) 수행 빈도 확인 -2
- Header 중에 Access-Control-Max-Age 값을 통해서 프리플라이트의 캐싱 기간을 확인할 수 있습니다.
4. 동일한 출처가 아닌 경우 : Cross Origin
💡 동일한 출처가 아닌 경우 : Cross Origin
- 브라우저에서 웹 서버로 리소스 요청을 하였을 때, 서버 내에서 이를 허용하지 않았고 프리플라이트 요청과정에서 문제가 발생하는 경우 403 오류가 발생하였고 에러메시지를 확인해 봅니다.