I have an app that uses a FastAPI backend and a Next.js frontend. In development and on production with stable origins, I am able to use the CORSMiddleware with no issues. However, I have deployed the Next.js frontend with Vercel, and want to take advantage of the automatic Preview deployments that Vercel makes with each git commit to allow for staging-type qualitative testing and sanity checks.
I'm running into CORS issues on the Preview deployments: since each Preview deployment uses an auto-generated URL of the pattern: <project-name>-<unique-hash>-<scope-slug>.vercel.app
, I can't add them directly to the allow_origins argument of the CORSMiddleware. Instead I am trying to add the pattern to the allow_origin_regex argument.
I am very new to regex, but was able to figure out a pattern that I've tested to work in REPL. However, because I'm having issues, I've switched to use an ultra-permissive regex of '.*' just to get anything to work but that has failed also.
main.py (relevant portions)
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
origins = [
"http://localhost",
"http://localhost:8080",
"http://localhost:3000",
"https://my-project-name.vercel.app"
]
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_origin_regex=".*",
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
I've looked at the FastAPI/Starlette cors.py file to see how it ingests and uses the origin regex and don't see where the problem would be. I've tested the same methods in REPL with no issues. I'm at a loss as to the next avenue to investigate in order to resolve this issue. Any assistance or pointers or "hey dummy you forgot this" comments are welcome.
Whenever a new deployment is created, Vercel will automatically generate a unique URL that is publicly available, and which is composed of the following pieces:
<project-name>-<unique-hash>-<scope-slug>.vercel.app
To allow requests from any Vercel deployment, use:
allow_origin_regex='https://.*\.vercel\.app'
To allow requests from a specific Vercel project, use:
allow_origin_regex='https://<project-name>-.*\.vercel\.app'
for instance:
allow_origin_regex = 'https://my-site-.*\.vercel\.app'
The example below is based on how FastAPI/Starlette's CORSMiddleware
works internally (see implementation here). The example shows that using the above regex, a match for an origin such as https://my-site-xadvghg2z-acme.vercel.app
is found.
import re
origin = 'https://my-site-xadvghg2z-acme.vercel.app'
allow_origin_regex = 'https://my-site-.*\.vercel\.app'
compiled_allow_origin_regex = re.compile(allow_origin_regex)
if (compiled_allow_origin_regex is not None
and compiled_allow_origin_regex.fullmatch(origin)):
print('Math found')
else:
print('No match found')
Please make sure to specify the correct protocol (e.g., http
, https
) and port(80
, 8000
, 3000
) in allow_origin_regex
.