보물창고 블로그

CORS(Cross-Origin Resource Sharing) 파헤치기 본문

웹 개발/Computer Science Note

CORS(Cross-Origin Resource Sharing) 파헤치기

홋 메 2025. 5. 18. 12:39
728x90

CORS(Cross-Origin Resource Sharing)는 브라우저가 웹 페이지의 원본이 아닌 다른 출처(도메인, 프로토콜, 포트)로부터 리소스를 로드하는 것을 허용하기 위한 HTTP 헤더 기반의 메커니즘입니다.  왜 CORS가 필요할까요? 이것을 이해하려면 동일 출처 정책(Same-Origin Policy)" 개념부터 이해해야 합니다. 

 

Same-Origin Policy브라우저의 보안 정책 하나로, "서로 다른 출처(origin)리소스 접근을 제한"합니다.
이는 사용자의 데이터를 악의적인 웹사이트로부터 보호하기 위한 기본 장치입니다. 여기서 간단하게 출처에 대해 알아보겠습니다.

✅ "출처(origin)"란?

출처(origin)다음 가지로 정의됩니다:

 

  1. 프로토콜 (http, https)
  2. 호스트 (도메인 이름, IP 주소)
  3. 포트 번호

출처가 다르면 SOP제한걸게 됩니다.                                                                                URL 동일 출처?

https://example.com:443 vs https://example.com:443 ✅ 동일
http://example.com vs https://example.com ❌ 다름 (프로토콜 다름)
https://example.com vs https://api.example.com ❌ 다름 (서브도메인 다름)
https://example.com:443 vs https://example.com:8443 ❌ 다름 (포트 다름)

 

그럼 왜 SOP가 필요할까요?

웹사이트는 로그인 상태 유지를 위해 쿠키나 세션사용합니다. 정보는 같은 도메인에서 요청할 자동으로 전송됩니다.

예를 들어:

 

  1. 사용자가 https://bank.com로그인하면, 쿠키에 인증 정보가 저장됩니다.
  2. 이후 사용자가 https://evil.com방문했을 때, 사이트가 자바스크립트를 통해 https://bank.com/transfer요청을 보내면?
  3. 브라우저는 쿠키를 자동으로 첨부해서 은행에 요청을 보냅니다!

이걸 허용하면 해킹이 매우 쉬워집니다.  그래서 브라우저는 "다른 출처(origin)"로의 요청을 막습니다. 공격을 CSRF(Cross-Site Request Forgery)라고 부릅니다.

 

CSRF 예시)

<!-- 악성 사이트에 숨겨진 폼 -->
<form action="https://bank.com/transfer" method="POST">
  <input type="hidden" name="to" value="hacker_account">
  <input type="hidden" name="amount" value="10000">
</form>
<script>document.forms[0].submit();</script>

 

사용자가 페이지를 보기만 해도, 은행 계좌에서 돈이 빠져나갈 있습니다. 이걸 막는 방법 하나가 Same-Origin Policy입니다. 그렇다면 웹앱(FE)은 https://myapp.com있고, API(BE)https://api.myapp.com있을 있다고 가정할 때, SOP를 어떻게 해결해야 할까요? 경우 브라우저가 기본 정책으로는 API 요청을 차단하므로, 서버가 "괜찮아! 요청해도 돼!"라고 말할 있는 수단이 필요합니다. 👉 그게 바로 CORS (Cross-Origin Resource Sharing)입니다. 이제 CORS의 작동 방식에 대해 알아보겠습니다.

CORS 기본적인 흐름은 다음과 같습니다.

  1. 클라이언트다른 출처로 HTTP 요청을 보냄
  2. 브라우저요청을 중간에서 가로채고, 서버가 CORS 허용을 했는지 확인
  3. 서버응답에 Access-Control-Allow-Origin 등의 CORS 관련 헤더를 포함
  4. 브라우저가 응답을 허용하거나 차단

위 흐름 중 2번 단계에서 브라우저가 자바스크립트 코드로 cross-origin 요청을 보낼 때, 단순요청인지 아닌지에 따라 브라우저는 preflight(사전요청)을 자동으로 수행합니다. 그렇다면 preFlight는 무엇일까요?

🚦 Preflight Request (사전 요청)

조건:

  • 메서드가 GET, POST, HEAD 외의
  • Content-Typeapplication/json 등 "단순하지 않은 타입"
  • 커스텀 헤더 포함
  • 쿠키 포함

동작:

브라우저가 먼저 OPTIONS 요청을 보내, 서버가 허용하는지 확인 → 허용되면 실제 요청 전송

 

예를 들면 웹앱(FE)은 https://myapp.com 있고, API(BE) https://api.myapp.com 있을  있다고 가정할 때,

웹앱에서 아래와 같이 요청을 보낸다고 가정해 보겠습니다.

fetch('http://api.example.com/data', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ name: 'John' }),
  credentials: 'include'
});

 

여기서 브라우저는 다음을 보고 판단합니다.

  • 메서드: POST괜찮음
  • Content-Type: application/json → ❌ "단순 요청 아님!" Preflight 요청 필요!

preflight가 필요하므로 브라우저에서  서버로 Preflight 요청 (OPTIONS) 을 하게 됩니다.

OPTIONS /data HTTP/1.1
Host: api.example.com
Origin: http://localhost:3000
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type

 

브라우저에서 preflight 요청을 받은 서버는 해당 요청을 받아서 CORS요청이 허용된 요청인지를 확인한 후, 허용된 CORS요청이면 다음과 같이 응답을 합니다.

HTTP/1.1 204 No Content
Access-Control-Allow-Origin: http://localhost:3000
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: Content-Type
Access-Control-Allow-Credentials: true

 

서버에서 온 preflight에 대한 응답 이후엔 브라우저에서 본 요청(actual request)을 하고, 서버에선 본 요청에 대한 응답을 하게 됩니다.

 

이번 시간에는 CORS에 대해서 알아보았습니다.

 

 

 

'웹 개발 > Computer Science Note' 카테고리의 다른 글

Spring Interceptor 파헤치기  (0) 2025.05.11
Spring filter 파헤치기  (0) 2025.05.10
JWT 파해치기  (0) 2025.05.03
Oauth 파헤치기  (1) 2025.05.02
Comments