Introduction
As web applications grow increasingly sophisticated, they often need to share resources across different origins or domains. However, to protect user's data and maintain security, browsers implement a policy called the Same-Origin Policy, which, by default, prevents resources from being shared across origins. Enter CORS, a mechanism that allows developers to override this default policy when necessary, enabling controlled sharing of resources across different origins.
In the context of FastAPI, configuring CORS appropriately is crucial for enabling your web application to interact with different services securely. This article will take you through how to configure CORS middleware in FastAPI, from simple configurations suitable for testing and development, to more advanced settings for production environments.
Configuring CORS Middleware
FastAPI uses Starlette for the web parts, which includes a middleware system. CORS is handled through a specific middleware class included in Starlette, which is also available in FastAPI.
To use it, you import CORSMiddleware
and then add it to your application:
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # Allows all origins
allow_credentials=True,
allow_methods=["*"], # Allows all methods
allow_headers=["*"], # Allows all headers
)
In this basic configuration, we're allowing all origins, methods, and headers, and we're also allowing credentials.
This configuration is permissive and useful for testing, but for production applications, you'll want to be more restrictive. In a real-world scenario, you'd replace the "*"
in allow_origins
with a list of the URLs that are allowed to communicate with your FastAPI application, and you'd restrict allow_methods
and allow_headers
to the specific methods and headers your application needs to function.
Handling CORS in FastAPI
Simple CORS Configuration
A simple CORS configuration in FastAPI can be implemented by allowing all origins, methods, and headers. This is typically used during development but is not recommended in a production environment due to security concerns.
Here's how a simple CORS configuration looks:
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # Allows all origins
allow_credentials=True,
allow_methods=["*"], # Allows all methods
allow_headers=["*"], # Allows all headers
)
Advanced CORS Configuration
In a production environment, you'll need a more advanced CORS configuration. This typically involves specifying a list of allowed origins, methods, and headers.
Here's an example of an advanced CORS configuration in FastAPI:
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
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=["GET", "POST"],
allow_headers=["Authorization", "Content-Type"],
)
In this example, we're allowing only specific origins, which are listed in the origins list. We're also only allowing the GET
and POST
methods, and only the Authorization
and Content-Type
headers.
Handling Specific Origins
There might be cases where you would want to specify certain origins to handle. This is done by adding them to the origins
list in the above example. However, what if you need to allow all subdomains of a particular domain?
This is where the allow_origin_regex
parameter comes into play. It allows you to specify a regular expression as the allowed origin. Here's an example:
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origin_regex='https?://.*\.example\.com',
allow_credentials=True,
allow_methods=["GET", "POST"],
allow_headers=["Authorization", "Content-Type"],
)
In this example, the application will allow any origin that matches the regular expression https?://.*\.example\.com
, which includes any subdomain of example.com
, using either the http or https
protocol.