Fastapi Cors
CORS (Cross-Origin Resource Sharing) is a security mechanism that allows or restricts web pages from requesting resources from different domains. When developing with a front-end and back-end separation architecture, the front-end page usually runs on different domains or ports, and CORS needs to be configured to properly access the back-end API.
* * *
## What is Cross-Origin Issue
The browser's same-origin policy restricts web pages from sending requests to different domains. For example:
| Front-end Address | Back-end API Address | Cross-Origin? |
| --- | --- | --- |
| `http://localhost:3000` | `http://localhost:8000` | Cross-origin (different ports) |
| `http://example.com` | `http://api.example.com` | Cross-origin (different domains) |
| `https://example.com` | `http://example.com` | Cross-origin (different protocols) |
| `http://example.com` | `http://example.com/api` | Same-origin (same domain, port, protocol) |
The three elements of same-origin: **protocol**, **domain**, **port**. Any difference means cross-origin.
* * *
## Configure CORS
FastAPI uses Starlette's `CORSMiddleware` to handle cross-origin requests:
## 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",# Front-end 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 Detailed Explanation
| Parameter | Type | Description | Recommended Value |
| --- | --- | --- | --- |
| `allow_origins` | `list` | List of origins allowed for cross-origin | Use specific domains in production |
| `allow_methods` | `list` | Allowed HTTP methods | `["GET", "POST", "PUT", "DELETE"]` |
| `allow_headers` | `list` | Allowed request headers | Configure as needed |
| `allow_credentials` | `bool` | Whether to allow cookies and authentication information | Set to `True` when authentication is needed |
| `expose_headers` | `list` | Response headers that front-end can access | Configure as needed |
| `max_age` | `int` | Cache time for preflight requests (seconds) | `600` |
> Using `["*"]` for `allow_origins` means allowing all origins, but this is incompatible with `allow_credentials=True`. If you need to carry cookies, you must specify specific origins.
* * *
## 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 origins:
## 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 front-end 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 cache for 10 minutes
)
> Using `allow_origins=["*"]` in production is a security risk and may lead to cross-site request forgery (CSRF) attacks. Be sure to specify the specific front-end domain.
* * *
## CORS Preflight Requests
Before sending certain cross-origin requests, the browser will first send an **OPTIONS** preflight request to ask the server if the actual request is allowed. The CORS middleware automatically handles preflight requests.
Conditions requiring preflight requests:
* Using non-simple methods like `PUT`, `DELETE`
* Request headers contain custom fields (such as `Authorization`)
* `Content-Type` is not `application/x-www-form-urlencoded`, `multipart/form-data`, or `text/plain`
> After setting `max_age`, the browser will cache the preflight result and will not resend preflight requests within the specified time, reducing network overhead.
* * *
## Summary
* CORS is a browser security mechanism that must be configured when developing with front-end and back-end separation
* Use `CORSMiddleware` to handle cross-origin requests
* In production environment, be sure to specify specific `allow_origins`, do not use `["*"]`
* `allow_credentials=True` is incompatible with `allow_origins=["*"]`
* CORS middleware automatically handles browser OPTIONS preflight requests
YouTip