I set up Session Middleware with my FastAPI backend to authenticate my React frontend users, which worked with domain=127.0.0.1
. Now that I've deployed both my frontend and my backend to two separate servers using Fly.io, the session cookies are no longer being accepted.
My frontend is deployed at XXX-ui.fly.dev
, and my backend is deployed at XXX-api.fly.dev
.
Here is the CORS config and Session Middleware config for my backend:
origins = [
"https://XXX-ui.fly.dev",
"https://XXX-ui.fly.dev:3000",
]
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
app.add_middleware(
SessionMiddleware,
secret_key=SECRET_KEY,
https_only=True,
max_age=3600,
same_site="none",
domain="XXX-ui.fly.dev",
)
Checking the devtools when I make the request, you can see the attempt is made to store the cookie, as shown by this screenshot:
The error I get is: Cookie “session” has been rejected for invalid domain.
It says in the SessionMiddleware docs for Starlette that session cookies can be configured for cross-domain requests, so long as the origins
are specified (not *
wildcard char).
So what am I missing here?
Thanks!!
After reading these MDN cookie docs, I realized that you simply cannot store cookies on cross-domain requests (xxx-UI.fly.dev
cannot save a cookie from xxx-API.fly.dev
).
The solution was to purchase my own unique domain, and then use DNS to route traffic to either the UI (domain) or the API (a subdomain of my purchased domain). HTTP only cookies can be set for subdomains, but not cross-domain.
This ultimately resulted in the following domain scheme:
the subdomain strategy works well.
For the FastAPI Session Middleware config, it looked like this:
app.add_middleware(
SessionMiddleware,
secret_key=SECRET_KEY,
https_only=True,
# 3600s = 1hr
max_age=3600,
same_site="none",
domain=".my-app.com",
)
The .
prefixing the domain in .my-app.com
allows all subdomains of my-app.com
to be accepted as well.