Skip to content

The Middlemen: Middleware and CORS

Middleware is a function that works with every request before it is processed by any specific path operation, and with every response before it is returned. It sits between the client and your application logic.

You can use middleware to:

  • Modify or check the request headers.
  • Process the request body.
  • Measure execution time.
  • Log requests.
  • Modify the response headers.

To create middleware in FastAPI, you use the @app.middleware("http") decorator. The middleware function takes two parameters: the request object and a call_next function.

The call_next function will pass the request to the corresponding path operation and return the response generated by it.

import time
from fastapi import FastAPI, Request
app = FastAPI()
@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
start_time = time.time()
# Pass request to the path operation
response = await call_next(request)
# Calculate time taken
process_time = time.time() - start_time
# Add a custom header to the response
response.headers["X-Process-Time"] = str(process_time)
return response

Understanding CORS (Cross-Origin Resource Sharing)

Section titled “Understanding CORS (Cross-Origin Resource Sharing)”

One of the most common middleware requirements is handling CORS. If your frontend (e.g., a React app) is running on http://localhost:3000 and your FastAPI backend is on http://localhost:8000, the web browser will block requests from the frontend to the backend by default for security reasons. This is known as the Same Origin Policy.

To allow your frontend to communicate with your backend, you must explicitly configure CORS to tell the browser which origins (domains) are allowed to access your API.

FastAPI provides a built-in CORSMiddleware to handle this easily. You should add it as the first middleware to ensure it catches options requests appropriately.

from fastapi.middleware.cors import CORSMiddleware
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=["*"],
)

In this configuration:

  • allow_origins: A list of origins that are allowed to make requests. You can use ["*"] to allow all, but specific lists are more secure.
  • allow_methods: HTTP methods allowed (GET, POST, etc.). ["*"] allows all.
  • allow_headers: Specific HTTP headers allowed.