Content
- Introduction
- What is CORS?
- CORS Basics
- Configuring FastAPI's CORSMiddleware
- Pre-Conclusion
- Discovering Starlette Configuration and Code Underneath
- Conclusion
Introduction
Cross-Origin Resource Sharing (CORS) is a critical mechanism that allows servers to control which origins (domains, schemes, or ports) can access their resources. In this article, we will delve into FastAPI's CORSMiddleware, understand its functionality, and learn how to configure it effectively.
What is CORS?
Think of CORS as a border protocol setup between the server side and the client side intended to allow resource hosts (any service that makes its data available via HTTP) to restrict which websites may access that data.
According to the FastAPI documentation, CORS or "Cross-Origin Resource Sharing" refers to the situations when a frontend running in a browser has JavaScript code that communicates with a backend, and the backend is in a different "origin" than the frontend.
According to Mozilla documentation, Cross-Origin Resource Sharing (CORS) is an HTTP-header based mechanism that allows a server to indicate any origins (domain, scheme, or port) other than its own from which a browser should permit loading resources.
In more technical terms, CORS, or Cross-Origin Resource Sharing, is an HTTP-header-based system that enables a server to specify which origins other than its own can access its resources, ensuring secure cross-origin data transfers while protecting against unauthorized requests.
CORS Basics
How CORS works
The Cross-Origin Resource Sharing standard works by adding new HTTP headers that let servers describe which origins are permitted to read that information from a web browser. Additionally, for HTTP request methods that can cause side-effects on server data (in particular, HTTP methods other than GET, or POST with certain MIME types), the specification mandates that browsers "preflight" the request, soliciting supported methods from the server with the HTTP OPTIONS request method, and then, upon "approval" from the server, sending the actual request. Servers can also inform clients whether "credentials" (such as Cookies and HTTP Authentication) should be sent with requests.
To achieve this, the backend must have a list of "allowed origins." In this case, it would have to include http://localhost:3000
or *
for the frontend to work correctly.
Handling errors
CORS failures result in errors but, for security reasons, specifics about the error are not available to JavaScript. The only way to determine what specifically went wrong is to look at the browser's console for details. For a deeper understanding of CORS, visit the Mozilla documentation.
Configuring FastAPI's CORSMiddleware
FastAPI provides its own middleware for handling CORS, offering granular control over cross-origin requests. We'll dive into the specifics of configuring FastAPI's CORSMiddleware step-by-step.
Requirements:
- Python 3
- Updated pip (best practice)
- Code editor
- Basic knowledge of pip installation and using a code editor
Step 1 (Should be done in the terminal):
Install FastAPI
pip install fastapi[all]
Step 2 (All other steps from here should be done in the code editor environment):
Necessary imports
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
Step 3:
Create an instance of the FastAPI framework and assign it to a variable named app
app = FastAPI()
Step 4:
A list of origins that you plan to be permitted to make cross-origin requests
origins = [
"http://localhost:3000",
]
Step 5:
Pass parameter configurations to app.add_middleware
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
Step 6:
Syntax for API endpoint
@app.get("/")
async def main():
return {"message": "Hello World"}
Here’s a link to a sample project on my github that utilizes this CORS configuration in the main.py file of the FASTAPI folder.
What the supported configuration arguments mean:
allow_origins
: A list of origins that should be permitted to make cross-origin requests. For example,['https://example.org', 'https://www.example.org']
. You can use['*']
to allow any origin.allow_origin_regex
: A regex string to match against origins that should be permitted to make cross-origin requests. For example,'https://.*\.example\.org'
.allow_methods
: A list of HTTP methods that should be allowed for cross-origin requests. Defaults to['GET']
. You can use['*']
to allow all standard methods.allow_headers
: A list of HTTP request headers that should be supported for cross-origin requests. Defaults to an empty list. You can use['*']
to allow all headers. The Accept, Accept-Language, Content-Language, and Content-Type headers are always allowed for CORS requests.allow_credentials
: Indicate that cookies should be supported for cross-origin requests. Defaults toFalse
.expose_headers
: Indicate any response headers that should be made accessible to the browser. Defaults to an empty list.max_age
: Sets a maximum time in seconds for browsers to cache CORS responses. Defaults to600
.
Important: In our Demo we used "*", so let’s talk about it. "*" a "wildcard" is used to say that all are allowed. But, like the joker it can get tricky.
If wildcards are used for allow_origins
, it will only allow certain types of communication, excluding everything that involves credentials: Cookies, Authorization headers like those used with Bearer Tokens, etc.
So, for everything to work correctly, it's better to specify explicitly the allowed origins.
Pre-Conclusion
FastAPI's CORSMiddleware empowers you to take control over cross-origin requests, securing your APIs while allowing legitimate access. With the knowledge gained from this article, you can confidently configure and utilize this middleware for your FastAPI projects, ensuring secure and efficient cross-origin data transfers.
Start building!
If you’re a nerd like me and curious about what code is down imports deeper in FastAPI CORSMiddleware, then it’s inception time.
Discovering Starlette Configuration and Code Underneath
So, I kept pressing ‘Go to definition’...
…and then I came across the ASGI gem Starlette
So, to keep the article length optimal, I’ll be writing about it in my next article. Keep checking my page, comment and like my posts.
Conclusion
Since this is not exactly where it ends (await the post conclusion :)), the conclusion will be in my next article.
Thank you for reading up to this point. Did you enjoy this article? Leave comments, questions, or other suggestions. Follow my page, contact me for technical articles, or collaborations on my LinkedIn.
Top comments (1)
Awesome work!