CORS

CORS (Cross-Origin Resource Sharing)

프론트엔드가 브라우저에서 돌아가고 API가 다른 주소에 있다면, CORS를 꼭 한 번은 만나게 돼요. 브라우저는 기본적으로 다른 "출처(origin)"에서 온 응답을 요청한 쪽이 읽지 못하게 막는데, CORS 설정이 바로 그 벽을 허물어 주는 장치예요. FastAPI에서는 CORSMiddleware 하나로 간단히 처리할 수 있어요.

출처: 공식문서

오리진 (Origin)

오리진(origin)은 프로토콜(http, https) + 도메인(myapp.com, localhost, localhost.tiangolo.com) + 포트(80, 443, 8080)의 조합이에요.

그래서 이들은 전부 서로 다른 오리진이에요:

  • http://localhost
  • https://localhost
  • http://localhost:8080

포트만 달라도 다른 오리진이 되는 거죠.

배경: 왜 CORS가 필요한가

예를 들어 프론트엔드가 http://localhost:8080에서 실행되고, 백엔드가 http://localhost에서 실행된다고 해 볼게요. 브라우저는 이 둘이 다른 오리진이라고 판단하고, 백엔드가 보내는 응답을 프론트엔드 JavaScript가 읽지 못하게 막아요. 이때 백엔드가 허용된 오리진 목록에 http://localhost:8080을 포함시키면, 해당 프론트엔드가 정상적으로 동작할 수 있어요.

즉 백엔드에 "허용된 오리진(allow origins)" 목록이 있어야 해요. 이 경우 :8080 프론트엔드가 제대로 동작하려면 목록에 http://localhost:8080이 들어 있어야 하죠.

CORSMiddleware 사용하기 (Use CORSMiddleware)

FastAPI 애플리케이션에서는 CORSMiddleware로 이걸 설정할 수 있어요. 순서는 이래요:

  1. CORSMiddleware를 임포트한다.
  2. 허용할 오리진 목록(문자열 리스트)을 만든다.
  3. 이를 **미들웨어(middleware)**로 FastAPI 애플리케이션에 추가한다.

말 그대로 코드로 보면 이렇죠:

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()

origins = [
    "http://localhost.tiangolo.com",
    "https://localhost.tiangolo.com",
    "http://localhost",
    "http://localhost:8080",
]

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)


@app.get("/")
async def main():
    return {"message": "Hello World"}

CORSMiddleware 구현이 기본적으로 쓰는 파라미터들은 기본값 자체가 제한적이에요. 그래서 브라우저가 Cross-Domain(다른 오리진) 맥락에서 특정 오리진·메서드·헤더를 쓰도록 허용하려면, 그걸 명시적으로 허용해 줘야 해요.

설정할 수 있는 파라미터들을 살펴볼게요:

  • allow_origins — 크로스 오리진 요청을 허용할 오리진 목록. 예: ['https://example.org', 'https://www.example.org']. ['*']를 쓰면 모든 오리진을 허용해요.
  • allow_origin_regex — 허용할 오리진을 매칭하는 정규식(regex) 문자열. 예: 'https://.*\.example\.org'.
  • allow_methods — 크로스 오리진 요청에서 허용할 HTTP 메서드 목록. 기본값은 ['GET']. ['*']로 모든 표준 메서드를 허용할 수 있어요.
  • allow_headers — 크로스 오리진 요청에서 지원할 HTTP 요청 헤더 목록. 기본값은 []. ['*']로 모든 헤더를 허용할 수 있어요.
    • Accept, Accept-Language, Content-Language, Content-Type 헤더는 단순 CORS 요청에서는 항상 허용돼요.
  • allow_credentials — 크로스 오리진 요청에서 쿠키를 지원할지 여부. 기본값은 False.
    • allow_credentialsTrueallow_origins, allow_methods, allow_headers 중 어느 것도 ['*']로 설정할 수 없어요. 모두 명시적으로 지정해야 해요.
  • expose_headers — 브라우저가 접근할 수 있게 노출할 응답 헤더. 기본값은 [].
  • max_age — 브라우저가 CORS 응답을 캐시할 최대 시간(초). 기본값은 600.

CORS 프리플라이트 요청 (CORS preflight requests)

OriginAccess-Control-Request-Method 헤더를 가진 OPTIONS 요청이 CORS 프리플라이트(preflight) 요청이에요. 브라우저가 실제 요청을 보내기 전에, 그 요청을 보내도 되는지 서버에 먼저 물어보는 거예요. FastAPI는 CORSMiddleware가 이 OPTIONS 요청에 자동으로 응답해 줘요.

더 알아보기 (Learn more)