FastAPI CORS Cross-Origin

CORS (Cross-Origin Resource Sharing) is a security mechanism that allows or restricts web pages from requesting resources from different domains. When frontend and backend are developed separately, the frontend page usually runs on a different domain or port, so CORS must be configured to access backend APIs normally.


What is the cross-origin problem

The browser's same-origin policy restricts web pages from sending requests to different domains. For example:

Frontend addressBackend API addressWhether cross-domain
http://localhost:3000http://localhost:8000Cross-origin (different port)
http://example.comhttp://api.example.comCross-origin (different domain)
https://example.comhttp://example.comCross-origin (different protocol)
http://example.comhttp://example.com/apiSame-origin (same domain, port, protocol)

Three elements of same-origin:Protocol、domain name、port, if any one differs, it is cross-origin.


Configure CORS

FastAPI uses Starlette'sCORSMiddlewareTo handle cross-origin:

Example

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

app = FastAPI()

# Configure CORS middleware
app.add_middleware(
    CORSMiddleware,
    allow_origins=[               # Allowed origins (domain list)
        "http://localhost:3000",   # Frontend development server
        "http://localhost:8080",
    ],
    allow_credentials=True,       # Allow cookies
    allow_methods=["*"],          # Allowed HTTP Methods
    allow_headers=["*"],          # Allowed Request Headers
)

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

CORS configuration parameters explained

ParameterTypeDescriptionrecommended value
allow_originslist[str]List of allowed cross-origin sourcesUse specific domains in production environment
allow_methodslist[str]Allowed HTTP methods["GET", "POST", "PUT", "DELETE"]
allow_headerslist[str]Allowed request headersOn-demand configuration
allow_credentialsboolWhether to allow carrying cookies and authentication informationSet to when authentication is requiredTrue
expose_headerslist[str]Response headers that the frontend can accessOn-demand configuration
max_ageintCache duration of preflight requests (seconds)600

allow_originsUsage["*"]Indicates allowing all origins, but this isallow_credentials=TrueIncompatible. If you need to carry cookies, you must specify a specific origin.


Development environment vs production environment

Development environment

For convenience during development, you can allow all origins:

Example

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

app = FastAPI()

# Development environment: allow all origins (for development only!)
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],         # Allow all origins
    allow_credentials=True,
    allow_methods=["*"],         # Allow All Methods
    allow_headers=["*"],         # Allow all request headers
)

Production Environment

Production environment must specify specific sources:

Example

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

app = FastAPI()

# Production environment: only allow specific domains
app.add_middleware(
    CORSMiddleware,
    allow_origins=[
        "https://example.com",           # Production Frontend Domain
        "https://www.example.com",       # Domain with www
    ],
    allow_credentials=True,
    allow_methods=["GET", "POST", "PUT", "DELETE"],
    allow_headers=["Authorization", "Content-Type"],
    max_age=600,                  # Preflight request cache for 10 minutes
)

Use in production environmentallow_origins=["*"]This is a security risk and may lead to cross-site request forgery (CSRF) attacks. Be sure to specify the specific frontend domain.


CORS preflight request

Before sending certain cross-origin requests, the browser first sends aOPTIONSPreflight request, asking the server whether the actual request is allowed. The CORS middleware automatically handles preflight requests.

Conditions for requests requiring preflight:

  • usesPUT、DELETENon-simple methods such as
  • The request header contains custom fields (such asAuthorization)
  • Content-Typeis notapplication/x-www-form-urlencoded、multipart/form-dataortext/plain

setmax_ageAfter that, the browser caches the preflight result and will not resend the preflight request within the specified time, reducing network overhead.


Summary

  • CORS is a browser security mechanism that must be configured in frontend-backend separated development.
  • UsageCORSMiddlewareHandling cross-origin requests
  • In production environment, be sure to specify the specificallow_origins, do not use["*"]
  • allow_credentials=Trueandallow_origins=["*"]incompatible
  • The CORS middleware automatically handles the browser's OPTIONS preflight requests.
other extensions