출처(Origin)
: 프로토콜 + 호스트 + 포트로 구성
- 모두 같아야 동일한 출처임
- EX) https://www.domain.com
- https:// -> 프로토콜
- www.domain.com -> 호스트
- :433 -> 포트
SOP(Same - Origin - Policy) - 동일 출처 정책
: 어떤 출처에서 불러온 문서나 스크립트가 다른 출처에서 가져온 리소스와 상호작용하는 것을 제한하는 중요한 보안 방식
- 기본적으로 출처가 다를 경우 서로 간의 문서나 스크립트에 접근을 할 수가 없고 극히 제한적인 객체에만 접근이 가능
- 동일한 출처 정책을 구현하는 브라우저는 한 출처에서 제공되는 웹 사이트 스크립트가 XMLHttpsRequest 또는 FetchAPI와 같은 메소드를 사용하여 다른 출처에 요청하는 것을 제한
CORS(Cross - Origin - Resource Sharing) - 교차 출처 리소스 공유
: 타사 API에 액세스해야 하는 필요성을 해결하기 위해 CORS 정책은 한 출처에서 제공하는 스크립트가 다른 출처의 리소스를 요청할 수 있는 방법을 결정
- 쉽게 말해, 서로 다른 도메인간에 자원을 공유하는 것을 의미
- CORS 정책은 요청 / 응답 상호 작용에 포함되어야 하는 특정 HTTP 헤더를 정의
- 서버가 요청을 허용할 출처를 통신할 수 있도록 함
- 그런 다음 브라우저는 스크립트가 응담에 액세스하는 것을 허용하거나 금지하여 이를 실행
- 나오게 된 배경)
- 현재는 프론트엔드 레이어와 API 서버 레이어를 따로 구성하는 경우가 유저많음 -> 웹 프론트엔트 사이트 따로, 서버 사이트 따로 둔다는 의미
- 이런 경우에는 보통 웹 프론트엔트에서 다른 도메인에 위치한 API 서버로 요청을 넣어야 하는 상황이 생김
- 하지만 과거에는 이런 기능이 당연하게 제공하지 않음
- 사실 원래는 도메인이 다르면 요청을 주고 받을 수 없게 하려는 게 웹 브라우저의 기본 정책이었음
- 과거의 웹사이트 구조

- 유저가 웹 브라우저 주소창에 주소값을 입력하면 해당하는 서버로 요청이 보내짐
- 서버에서는 응답을 할 때 HTML 페이지를 반환
- 즉, 하나의 서버에서 비즈니스 로직과 HTML 페이지 빌드를 같이 하는 게 일반적
- 왜 예전에는 같은 도메인에서 요청을 주고 받아야 했냐고 물으면 -> 개인정보 유출, 피싱 사이트와 같이 보안상 악의적인 행동을 하는 걸로 의심하였기 때문
- 하지만 시간이 지남에 따라 웹사이트에서 할 수 있는 일이 많아짐
- 단순히 문서 작성 뿐만 아니라 무언가 애플리케이션을 만들기 시작했고 그러한 상황들이 많아지다보니, 기존 웹 브라우저 보안 정책에 대해 불편한 점들이 조금씩 생기기 시작함
- 결국엔 웹 브라우저에서 공식적인 루트를 열어준 것이 바로 CORS
- 동작 원리)

- 일반적으로 이 CORS 세팅을 직접 할 일은 거의 없고, 웹 프론트엔드에서 요청을 넣을 때 CORS 옵션만 넣어주면 요청 헤더까지 알아서 다 넣어줌
- 웹 서버에서도 마찬가지로, 간단한 옵션을 통해서 CORS를 켜고 끌 수 있게 구성을 해둠
- 다시 말해, 프론트의 경우에는 Request Header 에 CORS 관련 옵션을 넣어주고, 서버의 경우에는 Response Header에 프론트의 요청을 허용한다는 내용을 넣어주면 됨
- 조금 특별한 점이 있다면, 그림 같은 HTTP OPTION 메소드

- 크로스 도메인 요청을 보내는 작업은 2번 보냄 (Client -> Server)
- 그래서 서버에서 웹 브라우저로부터 크로스 도메인 요청을 받으려면 동일한 라우터에 대해 OPTION 메소드 처리를 따로 하도록 작업 해야 함
- 보통은 서버 라이브러리에서 간편하게 알아서 해줌
- 원본 간 요청의 경우 브라우저에서 처리하는 3가지 유형이 있음
1. 간단한 요청(Simple Requests)

- 먼저 브라우저는 서버에 원본을 식별하는 헤더를 포함시켜 요청을 보냄
- 서버는 요청된 데이터로 응답하고 https://www.site.com으로 설정된 access-control-allow-origin 헤더도 포함됨
- 브라우저는 RequestHandler 메서드가 응답 데이터에 액세스 하도록 허용하여 이를 실행
- access-control-allow-origin 헤더 : 서버가 허용할 요청을 표시하는 데 사용할 수 있는 기본 CORS 헤더 중 하나
- 모든 곳에서 CORS를 허용하기 위해서는 모두를 의미하는 *를 입력하면 됨
- Example)
- (If 특정 출처에 대한 액세스 허용) Access-Control-Allow-Origin: https://www.site.com
- (If 모든 출처에 대한 액세스 허용) Access-Control-Allow-Origin: *
- 서버가 access-control-allow-origin 헤더로 응답하지 않거나 헤더 값이 요청 원본과 일치하지 않는 도메인인 경우, 브라우저는 응답이 스크립트로 다시 전달되는 것을 방지
- 단순 요청은 다음을 충족하는 요청
- GET, HEAD, POST 요청을 허용
- Accept, Accept-Language, Content-Language, Content-Type와 같은 User-Agent 헤어 또는 CORS Safelisted 헤더만 전송
- ReadableStream 개체를 사용하지 않음
- XMLHttpRequest.upload에 연결된 이벤트 리스너가 없음
2. 프리플라이트 요청(Preflighted Requests)

- 실제 요청을 보내기 전에 브라우저는 이러한 유형의 요청을 허용하는지 서버에 확인하는 요청
- 실행 전 요청은 다음 헤더를 포함하는 OPTIONS 요청임
- origin : 서버에 요청이 오는 출처를 알려준다.
- access-control-request-method : 요청이 구현하는 HTTP 메서드를 서버에 알려준다.
- access-control-request-headers : 요청이 포함된 헤더를 서버에 알려준다.
- 이에 대한 응답으로 서버는 다음 헤더로 응답하여 이 출처에서 이러한 종류의 요청을 수락할지 여부를 결정할 수 있음
- access-control-allow-origin : 서버가 허용할 원본
- access-control-allow-methods : 서버에서 허용할 쉼표로 구분된 메서드 목록
- access-control-allow-headers : 서버에서 허용하는 쉼표로 구분된 헤더 목록
- access-control-max-age : 실행 전 요청에 대한 응답을 캐시하는 시간(초)을 브라우저에 알려준다.
- 왜 Preflightes 요청을 해야할까 ?)
- 프리플라이트 요청을 통해 서버는 요청이 실행되기 전에 검사하고 허용 여부를 표시할 기회를 얻을 수 있기 때문
- 그리고 서버가 다른 출처에서 허용하지 않는 특정 요청을 차단함으로써 서버를 보호하는 데 도움을 줌
- 이 외에도 서버는 개발될 떄 허용하는 요청 및 헤더의 종류를 변경할 수 있음
3. 인증된 요청(Credentialed Requests)
- 인증 관련 헤더를 포함할 때 사용하는 요청
- 자격 증명은 쿠키, 인증 헤더 또는 TLS 클라이언트 인증서일 수 있음
- 클라이언트 측에서 자격 증명(Credentials)이 포함되어 있고 서버에서 Access-Control-Allow-Credentials가 true로 응답해야만 허용
- 이때, 서버는 반드시 '*'와일드카드를 지정하는 대신 Access-Control-Allow-Origin 헤더 갑셍 출처를 지정해야 함
'네트워크' 카테고리의 다른 글
13. 프록시 서버 (0) | 2025.02.28 |
---|---|
12. 쿠키와 세션 (0) | 2025.02.28 |
11. SOAP (1) | 2025.02.28 |
10. REST API + RESTful (1) | 2025.02.28 |
9. HTTPS (0) | 2025.02.28 |