Sling Academy
Home/FastAPI/Fixing FastAPI Error: Origin Blocked by CORS Policy

Fixing FastAPI Error: Origin Blocked by CORS Policy

Last updated: January 02, 2024

Overview

Cross-Origin Resource Sharing (CORS) is a security measure implemented by web browsers to prevent scripts on a webpage from making requests to a different domain than the one that served the webpage. In the context of FastAPI, this error typically occurs when a frontend running on one origin (domain, protocol, and port) tries to make a request to a FastAPI backend server hosted on a different origin, and the backend hasn’t been configured to allow such cross-origin requests. Here are some solutions to fix the FastAPI CORS error.

Utilize FastAPI CORS Middleware

FastAPI provides an easy way to handle CORS via its CORS Middleware. This method allows you to specify which origins are permitted to access your API, the methods allowed, and other parameters.

The process is as follows:

  1. Install FastAPI and its dependencies if you haven’t already.
  2. Import the CORS middleware from `fastapi.middleware.cors`.
  3. Add the CORS middleware to your FastAPI application instance.
  4. Specify the domains that should be allowed by setting the `allow_origins` parameter.
  5. Configure other CORS options as necessary, such as `allow_methods` or `allow_headers`.

Example:

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()

app.add_middleware(
    CORSMiddleware,
    allow_origins=["http://example.com"],  # Allows all origins
    allow_credentials=True,
    allow_methods=["*"],  # Allows all methods
    allow_headers=["*"],  # Allows all headers
)

@app.get("/")
async def read_root():
    return {"Hello": "World"}

Advantages and Limitations:

  • Advantage: Easy setup, and highly customizable.
  • Limitation: Incorrect configuration could expose your API to security risks if not properly handled.

Use FastAPI’s CORSMiddleware Factory

In cases where you need more granularity or you have multiple APIs with different CORS requirements, using a middleware factory can be suitable.

Steps that you can follow:

  1. Define a function that creates a new `CORSMiddleware` instance.
  2. Apply the middleware to a specific API router or the entire FastAPI application.

A small example:

from fastapi import FastAPI, APIRouter
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()
api_router = APIRouter()

def create_cors_middleware(allow_origins: list):
    return CORSMiddleware(
        allow_origins=allow_origins,
        allow_credentials=True,
        allow_methods=["*"],
        allow_headers=["*"],
    )

api_router.middleware(create_cors_middleware(["http://example.com"]))

@app.get("/")
async def read_root():
    return {"Hello": "World"}

app.include_router(api_router)

Advantages and Limitations:

  • Advantage: Greater flexibility for configuring different routers with varying CORS policies.
  • Limitation: Requires more thorough understanding of FastAPI’s router and middleware systems.

Configure CORS Pre-Flight Options Manually

For very specific cases or for implementing custom CORS behavior, you might want to handle CORS pre-flight OPTIONS requests manually. This involves creating endpoint handlers for the OPTIONS method.

Steps:

  1. Create a handler for the OPTIONS method on the endpoint(s) for which you want to configure CORS.
  2. Return the appropriate headers that signify CORS allowances, such as `Access-Control-Allow-Origin`.

Example:

from fastapi import FastAPI, Response

app = FastAPI()

@app.options("/")
async def preflight_handler():
    headers = {
        "Access-Control-Allow-Origin": "http://example.com",
        "Access-Control-Allow-Methods": "POST, GET",
        "Access-Control-Allow-Headers": "Content-Type",
    }
    return Response(status_code=200, headers=headers)

@app.get("/")
async def read_root():
    headers = {
        "Access-Control-Allow-Origin": "http://example.com",
    }
    return Response(content={"Hello": "World"}, headers=headers)

Advantages and Limitations:

  • Advantage: Provides the opportunity for very granular control over CORS behavior.
  • Limitation: More complex and error-prone, potential for maintenance challenges.

Next Article: Resolving FastAPI Error: ‘Could not import module ‘api”

Previous Article: FastAPI StreamingResponse AttributeError Fix

Series: Fixing Common Errors in FastAPI

FastAPI

You May Also Like

  • Popular useful built-in Jinja filters you should know
  • How to remove consecutive whitespace in rendered Jinja pages
  • How to format large numbers with thousand separators in Jinja template
  • How to format date time in Jinja templates
  • FastAPI + Jinja: How to create custom filters
  • How to pass variables from Python (FastAPI) to Jinja
  • How to decode Jinja response to string
  • How to create and use macros in Jinja
  • How to use namespace in Jinja
  • How to use if/ else in Jinja
  • How to use loops in Jinja
  • FastAPI + SQLAlchemy: Using cursor-based pagination
  • FastAPI: How to use macros in Jinja templates
  • Fixing Common Swagger UI Errors in FastAPI
  • FastAPI Error: 307 Temporary Redirect – Causes and Solutions
  • FastAPI Error: Expected UploadFile, received ‘str’
  • Resolving FastAPI ImportError: No Known Parent Package
  • FastAPI Error: No module named ‘pydantic_core._pydantic_core’
  • Resolving FastAPI 422 Error: Value is not a valid dict