Skillversitas

CORS

CORS (Cross-Origin Resource Sharing) is the browser security mechanism that lets a frontend on one origin (domain, scheme, port) call an API on another. The server announces which origins it accepts via response headers, and FastAPI provides the CORSMiddleware to do exactly that.

The Problem

A page at https://shop.example.com fetching from https://api.example.com is a cross-origin request. Browsers block the response unless the API sends Access-Control-Allow-Origin naming the requesting origin. The request often starts with an OPTIONS preflight that the server must answer with the allowed methods and headers.

Setting Up the Middleware

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

app = FastAPI()

app.add_middleware(
    CORSMiddleware,
    allow_origins=["https://shop.example.com", "http://localhost:3000"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

@app.get("/items/")
def list_items():
    return []

What Each Option Does

  • allow_origins - list of origins to accept; ["*"] allows any origin but is incompatible with allow_credentials=True.
  • allow_credentials=True - permits cookies and auth headers cross-origin; requires explicit origins.
  • allow_methods - HTTP methods for preflight; defaults to GET.
  • allow_headers - request headers allowed in the actual request.
  • allow_origin_regex - pattern alternative when origins are dynamic (e.g., a subdomain wildcard).

Testing CORS

curl -i -X OPTIONS http://127.0.0.1:8000/items/ \
  -H "Origin: http://localhost:3000" \
  -H "Access-Control-Request-Method: GET"

The response should include Access-Control-Allow-Origin: http://localhost:3000.

Common Gotchas

  • CORS is enforced by browsers, not the network: curl and mobile apps never see it, which hides misconfiguration.
  • With credentials, "*" for origins fails in modern browsers - list them explicitly.
  • The middleware must be added before routes are registered; keep one CORS middleware per app.

Summary

Add CORSMiddleware with an explicit allow_origins list (plus allow_credentials when using cookies) so browsers accept cross-origin API calls from your frontend. The middleware answers preflight OPTIONS requests automatically; test with curl -X OPTIONS and remember that non-browser clients never trigger CORS.