Files
xiaoxia-saas/apps/api/main.py
T
xiaoxia ea5bd47489
Deploy / Deploy Staging (push) Failing after 2s
Deploy / Build Production Runtime Images (push) Has been skipped
Deploy / Deploy Production (push) Has been skipped
Deploy / Production Browser E2E (push) Has been skipped
CI/CD Pipeline / Validate Code Quality And Tests (push) Has been cancelled
CI/CD Pipeline / Validate Code Quality And Tests (pull_request) Failing after 1m0s
Tests / test (pull_request) Failing after 1m0s
Tests / lint (pull_request) Failing after 1m0s
fix(P1-1): resolve CORS configuration security issue
2026-06-26 17:48:57 +08:00

84 lines
2.6 KiB
Python

import os
from app.api.router import api_router, health_router
from app.config import settings
from app.middleware.exceptions import (
APIException,
api_exception_handler,
general_exception_handler,
http_exception_handler,
validation_exception_handler,
)
from app.middleware.logging import RequestLoggingMiddleware
from fastapi import FastAPI
from fastapi.exceptions import RequestValidationError
from fastapi.middleware.cors import CORSMiddleware
from fastapi.middleware.gzip import GZipMiddleware
from starlette.exceptions import HTTPException as StarletteHTTPException
from starlette.staticfiles import StaticFiles
app = FastAPI(
title="小虾 SaaS API",
description="自动化剪辑 SaaS 平台 API",
version=settings.APP_VERSION,
docs_url="/docs",
redoc_url="/redoc",
)
app.add_exception_handler(APIException, api_exception_handler)
app.add_exception_handler(StarletteHTTPException, http_exception_handler)
app.add_exception_handler(RequestValidationError, validation_exception_handler)
app.add_exception_handler(Exception, general_exception_handler)
# P1-1: Fix CORS configuration security issue
# - allow_credentials=True is incompatible with allow_origins=["*"]
# - In production, only allow configured domains, not "*"
if settings.DEBUG:
allow_origins = settings.CORS_ORIGINS # Allow localhost in debug mode
else:
# In production, filter out any wildcard "*" origins
allow_origins = [origin for origin in settings.CORS_ORIGINS if origin != "*"]
if not allow_origins:
# Default to production domain if no valid origins configured
allow_origins = ["https://xiaoxiajianji.com"]
app.add_middleware(
CORSMiddleware,
allow_origins=allow_origins,
allow_credentials=True,
allow_methods=["GET", "POST", "PUT", "DELETE", "OPTIONS"],
allow_headers=["Authorization", "Content-Type"],
)
app.add_middleware(GZipMiddleware, minimum_size=1000)
app.add_middleware(RequestLoggingMiddleware)
app.include_router(health_router)
app.include_router(api_router)
_generated_files_dir = os.getenv("GENERATED_FILES_DIR", "/app/generated")
os.makedirs(_generated_files_dir, exist_ok=True)
app.mount(
os.getenv("GENERATED_FILES_URL_PREFIX", "/generated-files"),
StaticFiles(directory=_generated_files_dir),
name="generated-files",
)
def create_app() -> FastAPI:
return app
@app.get("/")
async def root():
return {
"service": settings.APP_NAME,
"status": "running",
"version": settings.APP_VERSION,
}
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host=settings.API_HOST, port=settings.API_PORT)