― CORS 개념부터 실제 설정 의미까지 정리

FastAPI로 API 서버를 만들때 반드시 마주치는 설정이 CORS이다.
특히 프론트엔드(React, Vue 등)와 API 서버를 분리해서 개발할 때 CORS 설정이 없으면 브라우저에서 요청이 막히는 현상이 발생한다.
이 글에서는 CORS가 무엇인지 → 왜 필요한지 → FastAPI에서 설정이 어떤 의미인지를 흐름대로 정리한다.
1. CORS란?
Cross-Origin Resource Sharing 의 약자로

👉 서로 다른 출처(origin) 간에 리소스를 공유할 수 있도록 허용하는 브라우저 보안 규칙이다.
여기서 핵심은 “브라우저 보안 정책” 이라는 점이다.
CORS는 서버가 요청을 막는 기술이 아니라, 브라우저가 응답을 읽지 못하게 막는 규칙이다.
2. CORS에서 Origin(출처)란?
브라우저는 요청을 보낼 때 다음 3가지를 묶어서 출처(origin)를 판단한다.
- 프로토콜 (http / https)
- 호스트 (도메인 또는 IP)
- 포트 번호
예를 들어,
- http://localhost:3000
- http://XXX.XXX.XXX.XXX:8003
이 두 주소는 포트가 다르므로 서로 다른 origin이다.
이 상태에서 브라우저에서 3000 → 8003으로 API 요청을 보내면 Cross-Origin 요청이 된다.
3. 왜 CORS가 필요한가 ?
CORS를 이해하려면 먼저 SOP(Same-Origin Policy) 를 알아야 한다.
SOP란
- 같은 origin에서 온 웹 페이지의 요청만 안전하다고 가정하는 기본 보안 정책이다.
이 정책이 없으면 다음과 같은 문제가 생긴다.
- 사용자가 은행 사이트에 로그인함
- 같은 브라우저 탭에서 악성 사이트에 접속함
- 악성 사이트의 JavaScript가 은행 API를 호출함
- 로그인 쿠키가 자동으로 붙어서 개인정보가 탈취됨
이런 사고를 막기 위해 브라우저는:
- 다른 origin으로 요청은 보내도
- 그 응답을 JavaScript가 읽는 것은 기본적으로 차단한다.
이 차단을 서버가 “이 요청은 안전하다”고 명시적으로 허용해주는 방식이 바로 CORS이다.
4. CORS는 언제 문제가 되는가
중요한 사실 하나가 있다.
- CORS는 브라우저에서만 문제가 된다
- Postman, curl, Python requests 같은 도구에는 거의 영향이 없다
즉,
- React/Vue에서 API 호출 → CORS 에러 발생
- 같은 API를 curl로 호출 → 정상 동작
이 차이는 브라우저가 보안 정책을 적용하기 때문이다.
5. 브라우저의 CORS 처리 흐름
1️⃣ 단순 요청(Simple Request)
조건을 만족하면 바로 요청을 보내고, 응답 헤더를 보고 허용 여부를 판단한다.
서버 응답에 아래 헤더가 있으면:
Access-Control-Allow-Origin: http://localhost:3000
브라우저는 응답을 JavaScript 코드에 전달한다.
2️⃣ 사전 요청(Preflight Request)
조금이라도 위험해 보이면 브라우저는 OPTIONS 요청을 먼저 보낸다.
예:
- POST 요청
- Content-Type: application/json
- Authorization 헤더 사용
브라우저의 질문
“이 origin에서 이런 메서드랑 헤더로 요청 보내도 되나요?”
서버가 OK 응답을 주면 그제서야 실제 요청을 보낸다.
6. FastAPI에서 CORS 설정이 하는 일
FastAPI에서는 CORSMiddleware를 통해 CORS 관련 응답 헤더를 자동으로 추가한다.
fastAPI코드의 cors 설정 부분
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
이 설정은 “이 API 서버는 어떤 origin의 브라우저 요청이든 허용하겠다” 라는 의미이다.
1. allow_origins
allow_origins=["*"]
- 모든 origin에서 온 요청의 응답을 읽을 수 있도록 허용함
- 개발 단계에서는 편리하지만 운영 환경에서는 위험할 수 있음
운영 환경에서는 보통:
allow_origins=["https://frontend.example.com"]
처럼 명시적으로 제한한다.
2. allow_methods
allow_methods=["*"]
- GET, POST, PUT, DELETE 등 모든 HTTP 메서드를 허용함
3. allow_headers
allow_headers=["*"]
- 브라우저가 보내는 모든 헤더를 허용함
- Authorization, Content-Type 같은 헤더 사용 시 필수적이다
4. allow_credentials
allow_credentials=True
- 쿠키, 세션, 인증 정보를 포함한 요청을 허용함
- 로그인 세션 기반 서비스에서는 거의 필수다
⚠️ 주의점
allow_credentials=True 인 경우
allow_origins=["*"] 와 함께 쓰는 것은 권장되지 않는다.
운영에서는 반드시 origin을 명시하는 것이 원칙이다.
8. CORS 에러의 정체
브라우저 콘솔에 자주 보이는 에러 메시지:
No 'Access-Control-Allow-Origin' header is present …
이 의미는:
- 서버가 응답을 주지 않았다는 뜻이 아니다
- 브라우저가 응답을 FE 코드에 넘기지 않았다는 뜻이다
즉, 서버는 정상 동작 중일 가능성이 높다.
9. 권장 설정
개발 환경
allow_origins=["*"]
allow_methods=["*"]
allow_headers=["*"]
운영 환경
allow_origins=["https://frontend.company.com"]
allow_credentials=True
allow_methods=["GET", "POST"]
allow_headers=["Content-Type", "Authorization"]
필요한 만큼만 열어두는 것이 보안상 가장 안전하다.
마무리
CORS는 FastAPI의 문제가 아니라 브라우저 보안 모델의 일부이다.
FastAPI에서 CORS 설정을 한다는 것은,
“이 API는 특정 브라우저 출처에서 호출되어도 안전하다”
라고 서버가 선언하는 작업이다.
프론트엔드와 백엔드를 분리해서 개발한다면,
CORS 설정은 선택이 아니라 필수라는 점을 기억하면 된다.
'Development environment' 카테고리의 다른 글
| [FastAPI] FastAPI 개발하기4 - Request / Response 모델(Pydantic) (1) | 2026.02.13 |
|---|---|
| [FastAPI] FastAPI 개발하기3 - 엔드포인트와 라우터 (0) | 2026.02.12 |
| [FastAPI] FastAPI 개발하기 1- 환경 셋팅 및 실행명령어 (0) | 2026.02.06 |
| [DBeaver] DBeaver 설치 및 연동하기 (0) | 2026.02.03 |
| [Git] Git 커밋 메세지 규칙 + 커밋 수정하기 (0) | 2025.12.17 |