DEV Community

Claret Ibeawuchi
Claret Ibeawuchi

Posted on • Updated on

Demystifying FastAPI's CORSMiddleware for Cross-Origin Requests

Content

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?

Meme of a duck acting as a sea border patrol

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]
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Step 3:

Create an instance of the FastAPI framework and assign it to a variable named app

app = FastAPI()
Enter fullscreen mode Exit fullscreen mode

Step 4:

A list of origins that you plan to be permitted to make cross-origin requests

origins = [
    "http://localhost:3000",
]
Enter fullscreen mode Exit fullscreen mode

Step 5:

Pass parameter configurations to app.add_middleware

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)
Enter fullscreen mode Exit fullscreen mode

Step 6:

Syntax for API endpoint

@app.get("/")
async def main():
    return {"message": "Hello World"}
Enter fullscreen mode Exit fullscreen mode

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 to False.

  • 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 to 600.

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.
Picture of a wild card

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!

Inception meme

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’...

Screenshot of my cursor on Go to definition
...

A few moments later

…and then I came across the ASGI gem Starlette

Screenshot of a starlete cors.py page

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)

Collapse
 
gloriakaduru profile image
Gloria Kaduru

Awesome work!