CORS(Cross-Origin Resource Sharing, 교차 출처 리소스 공유)는 한 **출처(origin)**의 웹 페이지가 다른 출처의 API를 호출할 수 있는지 제어하는 브라우저 보안 메커니즘입니다. FastAPI는 내장 **CORSMiddleware**로 이를 구성합니다. 다른 도메인/포트의 프론트엔드가 API를 호출할 때마다 CORS를 마주하게 됩니다.
CORS가 다루는 문제
http://localhost:3000의 React 앱이 http://localhost:8000의 API를 호출하는 것은
교차 출처(다른 포트)입니다. 브라우저는 API가 그 출처를 허용하는 CORS 헤더를
보내지 않는 한 응답을 차단합니다.
(origin = scheme + host + port)
CORSMiddleware 구성
from fastapi.middleware.cors import CORSMiddleware
app.add_middleware(
CORSMiddleware,
allow_origins=["https://app.example.com", "http://localhost:3000"], # 출처 허용 목록
allow_credentials=True, # 쿠키/인증 허용 ("*"가 아닌 특정 출처 필요)
allow_methods=["*"], # 또는 ["GET", "POST", ...]
allow_headers=["*"],
)
middleware는 필요한 CORS 응답 헤더를 추가하여, 어떤 출처, 메서드, 헤더가 허용되는지 브라우저에 알립니다. 브라우저가 이 규칙을 강제합니다.
보안: 출처를 제한하세요 ("*"를 사용하지 마세요)
# ❌ 모든 출처 허용 — 편리하지만 인증/비공개 API에는 안전하지 않음
allow_origins=["*"]
# ✅ 알려진 프론트엔드 출처로 제한 (허용 목록)
allow_origins=["https://app.example.com"]
# 참고: allow_credentials=True는 allow_origins=["*"]와 호환되지 않습니다
프로덕션에서는 * 대신 allow_origins를 허용 목록으로 제한하세요. 또한 자격 증명(쿠키/인증) 허용은 특정 출처를 요구합니다. 와일드카드는 자격 증명과 함께 허용되지 않습니다.
핵심 오해
CORS는 서버가 아니라 브라우저가 강제합니다. 비브라우저 클라이언트(curl, Postman,
다른 서버)로부터 API를 보호하지 않습니다 — 이들은 CORS를 완전히 무시합니다.
CORS는 다른 출처의 브라우저 JavaScript가 무엇을 할 수 있는지만 규율합니다.
왜 중요한가
CORS는 웹 개발에서 가장 흔한 걸림돌 중 하나입니다. 거의 모든 프론트엔드-API 구성이 이를 마주합니다(특히 다른 포트를 사용하는 로컬 개발, 그리고 별도 프론트엔드 도메인이 있는 프로덕션에서). FastAPI의 CORSMiddleware로 구성하는 방법을 아는 것은 실용적이고 자주 필요한 지식입니다.
왜 존재하는지(브라우저 동일 출처 보안), 서버가 응답 헤더를 통해 어떻게 opt-in하는지, 그리고 어떻게 구성하는지(허용된 출처, 메서드, 헤더, 자격 증명)를 이해하는 것은 요청이 차단되지 않고 프론트엔드를 FastAPI API에 연결하는 데 필요합니다.
마찬가지로 중요한 것은 이를 안전하게 구성하는 것입니다 — allow_origins를 허용 목록인 *이 아닌 특정 목록으로 제한하는 것(그리고 자격 증명이 와일드카드와 호환되지 않음을 이해하는 것) — 그리고 CORS는 브라우저 메커니즘이지 API 인가가 아니다라는 핵심 오해를 파악하는 것(비브라우저 클라이언트로부터 보호하지 않음)입니다.
CORS를 올바르고 안전하게 설정하는 방법을 아는 것은 웹 프론트엔드가 사용하는 모든 FastAPI API에 중요한 일상 지식입니다.
