FastAPI ErrorHandling 과 CORS (2) - 대안 파악

2025. 2. 15. 18:48·탐구 생활/FastAPI CORS

 

Starlette 와 FastAPI 의 ISSUE(link,link) 에서는 다음의 해결법이 논의 되었습니다.

논의된 해결법

1. FastAPI 앱을 CORSMiddleware로 감싸기

from: thomasleveil

from starlette.applications import Starlette
from starlette.authentication import AuthenticationBackend, AuthenticationError
from starlette.exceptions import HTTPException
from starlette.middleware.authentication import AuthenticationMiddleware
from starlette.middleware.cors import CORSMiddleware
from starlette.responses import JSONResponse

import uvicorn

class DumbAuthBackend(AuthenticationBackend):
    async def authenticate(self, request):
        raise AuthenticationError("You will never be authenticated!")

app = Starlette(debug=True)

# Global authentication
app.add_middleware(AuthenticationMiddleware, backend=DumbAuthBackend())

@app.route('/')
async def index(request):
    return JSONResponse({"hello": "world"})

if __name__ == '__main__':
    uvicorn.run(
        CORSMiddleware(app=app, allow_origins=["*"]),
        host='0.0.0.0',
        port=8000
    )

 

CORSMiddleware가 자체적으로 ASGI 앱이므로 FastAPI 앱을 감싸도록 구성합니다. 이를 통해 outermost middleware 가 CORSMiddleware 가 되기 때문에 CORS 헤더 문제를 자연스럽게 해결하게 됩니다.

평가

  • ✅ 장점: 비교적 간단하게 적용 가능
  • ⚠️ 단점: 초보자에게는 이러한 wrapping 개념이 이해하기 어려울 수 있습니다.

이렇게 문제를 해결하는 것은 Starlette App 구성이 갖는 문제를 또다른 ASGI App 을 만들어서 해결하는 것으로 뭔가 와닿지 않습니다.

차라리 Starlette 측에서 CORSMiddleware 를 추가하는 새로운 방법을 제공하는게 맞을 것입니다.

2. ExceptionHandler에서 직접 CORS 헤더 추가

from: ddahan

def add_cors(request: Request, response: JSONResponse) -> JSONResponse:
    """
    CORS headers are not automatically added to error handlers with FastAPI
    cf. https://github.com/fastapi/fastapi/discussions/8027
    """
    cors_headers = {
        "Access-Control-Allow-Methods": ", ".join(settings.CORS_ALLOW_METHODS),
        "Access-Control-Allow-Headers": ", ".join(settings.CORS_ALLOW_HEADERS),
        "Access-Control-Allow-Credentials": str(settings.CORS_ALLOW_CREDENTIALS).lower(),
    }

    # If the origin is in the allowed list, add it to the CORS headers
    origin = request.headers.get("origin")
    if origin in settings.CORS_ALLOW_ORIGIN:
        cors_headers["Access-Control-Allow-Origin"] = origin

    response.headers.update(cors_headers)
    return response

def internal_exception_handler(request: Request, exc: Exception) -> JSONResponse:
    response = JSONResponse(
        status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
        content={
            "errors": {
                "general": [
                    "An unknown error has occurred. Please contact an administrator."
                ]
            }
        },
    )
    return add_cors(request, response)

 

settings 로 CORS 관련 세팅을 전역적으로 관리하려고 하는 시도가 돋보입니다. 

ExceptionHandler 는 ServerErrorMiddleware 와 ExceptionMiddleware 에 적용되기 때문에 CORSMiddleware 를 우회하여 반환되는 이유로 CORS 헤더가 누락되는 문제를 해결할 수 있습니다.

평가 

  • ✅ 장점: 원하는 예외 상황에서 정확하게 CORS 헤더를 제어할 수 있습니다.
  • ⚠️ 단점: 전역적으로 처리해야 할 CORS 헤더를 개별 ExceptionHandler에서 설정하는 것은 비효율적이며 비표준적입니다.

비록 CORS 관련 세팅을 전역적으로 처리하려고 했으나 본질적으로 예외 처리 시 응답에 CORS 헤더를 수동으로 추가하는 것입니다. CORS에 처리는 Applciation 전역적으로 처리되어야 하는데, 지엽적인 처리에 머물러 있는것 같아 아쉽습니다.


결론

지극히 개인적인 의견입니다.

CORS Middleware 로 FastAPI application 을 감싸는 행위는 이해하기 어려습니다. 과연 라이브러리 수준에서 정식으로 권장하는 문제라고 받아들일 수 있을까요?

또한 ExceptionHandler 에서 직접 header 를 추가하는것도 이상합니다. 일부 경우를 제외하고 CORS 에 대한 대응은 application 전역적인 처리가 되어야 하기 때문입니다.

 

제 3의 해법이 필요해 보입니다, 그리고 이 문제를 해결하는 과정은 "FastAPI ErrorHandling 과 CORS (3) - 문제 해결" 에 정리했습니다.

'탐구 생활 > FastAPI CORS' 카테고리의 다른 글

FastAPI ErrorHandling 과 CORS (3) - 문제 해결  (0) 2025.02.22
FastAPI ErrorHandling 과 CORS (1) - 문제 파악  (0) 2025.02.10
'탐구 생활/FastAPI CORS' 카테고리의 다른 글
  • FastAPI ErrorHandling 과 CORS (3) - 문제 해결
  • FastAPI ErrorHandling 과 CORS (1) - 문제 파악
개발프로브
개발프로브
가볍게, 오랫동안 기록하고 싶은 블로그입니다.
  • 개발프로브
    ProbeHub
    개발프로브
  • 전체
    오늘
    어제
    • 분류 전체보기 (56)
      • 탐구 생활 (47)
        • 개발 탐구 (8)
        • FastAPI CORS (3)
        • FastAPI Log (4)
        • gRPC&Python (4)
        • SpringBoot 파헤치기 (2)
        • Python Monorepo (3)
        • Python 과 zstd (2)
        • Python (4)
        • FastAPI (4)
        • Terraform (8)
        • MSA (0)
        • GraphQL (2)
        • 데이터베이스 (2)
        • 네트워크 (0)
      • 기초 지식 (9)
        • Terraform (2)
        • MSA (5)
        • K8s (2)
  • 블로그 메뉴

    • 링크

      • github
      • stackoverflow
    • 공지사항

    • 인기 글

    • 태그

      python graviton
      백엔드 성능
      FastAPI
      brotli
      fastapi logging
      오블완
      RDBMS 성능 최적화
      python 성능 개선
      MSA
      sqlalchemy
      python 불변 객체
      python arn64
      ORM 성능
      gzip
      ORM 성능 최적화
      fastapi cors
      zstd
      grpc
      springboot
      Terraform
      python amd64
      티스토리챌린지
      rest vs grpc
      granian
      java
      spring 트랜잭션
      PostgreSQL
      Python
      django 성능 개선
      ORM 문제
    • 최근 댓글

    • 최근 글

    • hELLO· Designed By정상우.v4.10.0
    개발프로브
    FastAPI ErrorHandling 과 CORS (2) - 대안 파악
    상단으로

    티스토리툴바