본문 바로가기

개발/fastapi

CORS란 무엇인가?

반응형

 

from fastapi.middleware.cors import CORSMiddleware # CORS 처리를 위한 미들웨어

 

fastapi의 main파일에 있는 하나의 라이브러리를 보자

여기 있는 CORS란 무엇이고 Middleware란 무엇인고?

 

CORS (Cross-Origin Resource Sharing)**는 웹 브라우저의 보안 정책 중 하나입니다.

 

 

🔒 브라우저의 동일 출처 정책 (Same-Origin Policy)

브라우저는 기본적으로 보안상의 이유로 다른 출처(Origin)의 리소스에 접근하는 것을 차단합니다.

 

출처(Origin) = 프로토콜 + 도메인 + 포트
예시:
- http://localhost:3000 (React 앱)
- http://localhost:8000 (FastAPI 서버)
→ 포트가 다르므로 "다른 출처"로 인식!

 

 

// React에서 FastAPI로 요청 시
axios.get('http://localhost:8000/posts')

 

 

//브라우저 콘솔에러

 

Access to XMLHttpRequest at 'http://localhost:8000/posts' 
from origin 'http://localhost:3000' has been blocked by CORS policy: 
No 'Access-Control-Allow-Origin' header is present on the requested resource.

 

 

코드에서 CORS설정 부분을 보면아래와 같다.

 

# CORS 미들웨어 설정
app.add_middleware(
    CORSMiddleware,
    allow_origins=["http://localhost:3000"],  # React 개발 서버 주소
    allow_credentials=True,                   # 인증 정보 포함 허용
    allow_methods=["*"],                      # 모든 HTTP 메서드 허용
    allow_headers=["*"],                      # 모든 헤더 허용
)

 

 

📊 CORS 설정 옵션 상세 설명

1. allow_origins - 허용할 출처 설정

# 개발 환경
allow_origins=["http://localhost:3000"]

# 프로덕션 환경 (여러 도메인 허용)
allow_origins=[
    "https://myapp.com",
    "https://www.myapp.com", 
    "https://admin.myapp.com"
]

# 모든 출처 허용 (보안상 위험!)
allow_origins=["*"]

 

2. allow_credentials - 인증 정보 허용

# 쿠키, Authorization 헤더 등 인증 정보 허용
allow_credentials=True

# 인증 정보 차단
allow_credentials=False

 

3. allow_methods - HTTP 메서드 허용

# 모든 HTTP 메서드 허용
allow_methods=["*"]

# 특정 메서드만 허용
allow_methods=["GET", "POST", "PUT", "DELETE"]

# 읽기 전용
allow_methods=["GET"]

 

4. allow_headers - HTTP 헤더 허용

# 모든 헤더 허용
allow_headers=["*"]

# 특정 헤더만 허용
allow_headers=["Content-Type", "Authorization"]

 

 

 

🔍 CORS 동작 원리

1. Simple Request (단순 요청)

특정 조건을 만족하는 요청은 바로 전송됩니다:

// GET 요청 (단순 요청)
axios.get('http://localhost:8000/posts')

 

서버 응답에 포함되는 CORS 헤더:

Access-Control-Allow-Origin: http://localhost:3000
Access-Control-Allow-Credentials: true

 

2. Preflight Request (사전 요청)

복잡한 요청 전에 브라우저가 OPTIONS 요청을 먼저 보냅니다:

// POST 요청 (사전 요청 필요)
axios.post('http://localhost:8000/posts', {
    title: "제목",
    content: "내용"
})

 

 

브라우저가 보내는 사전 요청:

OPTIONS /posts HTTP/1.1
Origin: http://localhost:3000
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type

 

 

서버의 사전 요청 응답:

Access-Control-Allow-Origin: http://localhost:3000
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Content-Type
Access-Control-Max-Age: 86400

 

 

🛡️ 보안 고려사항

✅ 안전한 CORS 설정 (프로덕션)

app.add_middleware(
    CORSMiddleware,
    allow_origins=[
        "https://myapp.com",           # 실제 도메인만 허용
        "https://www.myapp.com"        
    ],
    allow_credentials=True,            # 필요한 경우만
    allow_methods=["GET", "POST", "PUT", "DELETE"],  # 필요한 메서드만
    allow_headers=["Content-Type", "Authorization"], # 필요한 헤더만
)

 

 

❌ 위험한 CORS 설정

app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],              # 모든 도메인 허용 (위험!)
    allow_credentials=True,           # 인증정보 + 와일드카드 (매우 위험!)
    allow_methods=["*"],              
    allow_headers=["*"],              
)

 

 

 

1. 개발 환경에서 CORS 에러 발생 시

문제: React 앱에서 API 호출 시 CORS 에러

Access to XMLHttpRequest blocked by CORS policy

해결책:

# FastAPI에 CORS 미들웨어 추가
app.add_middleware(
    CORSMiddleware,
    allow_origins=["http://localhost:3000"],  # React 개발 서버
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

 

2. 프로덕션 환경에서 CORS 설정

import os

# 환경변수로 허용 도메인 관리
ALLOWED_ORIGINS = os.getenv("ALLOWED_ORIGINS", "http://localhost:3000").split(",")

app.add_middleware(
    CORSMiddleware,
    allow_origins=ALLOWED_ORIGINS,
    allow_credentials=True,
    allow_methods=["GET", "POST", "PUT", "DELETE"],
    allow_headers=["Content-Type", "Authorization"],
)

 

💡 CORS가 필요한 이유

  1. 보안: 악성 웹사이트가 사용자 모르게 다른 사이트의 API 호출하는 것을 방지
  2. 사용자 프라이버시: 민감한 데이터가 승인되지 않은 도메인으로 전송되는 것을 차단
  3. CSRF 공격 방지: Cross-Site Request Forgery 공격을 막음

🎯 우리 블로그 프로젝트에서 CORS의 역할

React App (localhost:3000)  ──HTTP 요청──→  FastAPI (localhost:8000)
         ↑                                           ↓
    CORS 허용됨 ←──── Access-Control-Allow-Origin ──┘

 

 

CORS 설정이 없다면 React 앱에서 FastAPI로 데이터를 요청할 수 없어서 블로그가 작동하지 않습니다!

이것이 바로 CORSMiddleware가 우리 블로그 프로젝트에서 필수적인 이유입니다! 🚀

반응형