🌏 中文版
TL;DR
The main backend runs on a remote HTTPS server (server-dev.daodao.so), so the auth_token cookie is bound to that domain. When the frontend calls the local AI backend (localhost:8002), the browser does not attach the cookie — regardless of credentials: "include" — causing the AI backend to treat every request as unauthenticated and return an empty array.
Context
A front-end/back-end separated architecture with three services:
- Frontend:
http://localhost:3001 - AI backend:
http://localhost:8002(local) - Main backend:
https://server-dev.daodao.so(remote dev server)
While building the recommendation feature, I called GET /api/v1/recommendation/topic_cards. The database had data, the user was logged in, but the response was always:
{ "success": true, "data": [] }
The Problem
The API returned empty data with no errors, so my first instinct was that the database had no data or the query filters were too strict.
I dug into the AI backend’s recommendation.py:
if not user_id:
return build_success_response(data=[])
user_id was None. Looking further into dependencies.py:
def get_current_user(request: Request, ...):
token = request.cookies.get("auth_token")
if not token:
return None
No auth_token cookie was present.
But in DevTools Network, requests to the main backend clearly showed auth_token being sent…
Investigation
My initial guess was the secure: true flag in cookie-config.ts — since the local environment runs over HTTP, secure cookies wouldn’t be stored. But looking more carefully, auth_token was indeed in the browser’s cookie list; it just wasn’t being sent to localhost:8002.
The frontend’s fetchAiBackend had credentials: "include" set, which should attach cookies on cross-origin requests — but it had no effect.
Root Cause & Fix
Cookies are domain-scoped.
auth_token is set by server-dev.daodao.so (over HTTPS) during login. The browser binds this cookie to that domain. When a request goes to http://localhost:8002, the browser will not include cookies that belong to server-dev.daodao.so — even with credentials: "include".
Why This Happens
The browser’s cookie security model works as follows:
- When a cookie is stored, it is associated with the
domainof the server that set it (defaults to the host in theSet-Cookieresponse header) credentials: "include"tells the browser: “include cookies that belong to the target domain on cross-origin requests”- But
auth_token’s domain isserver-dev.daodao.so, notlocalhost - So when making a request to
localhost:8002, this cookie falls outside the scope of “cookies belonging to the target domain”
Requests to the same remote main backend work fine because the target domain matches the cookie’s domain.
The full failure chain:
request → localhost:8002
→ fetchAiBackend: credentials: "include"
→ browser looks up cookies for localhost → auth_token not found
→ FastAPI get_current_user() → return None
→ if not user_id: return []
Takeaway
credentials: "include" does not mean “send all cookies” — it means “send cookies that belong to this domain.” When developing with multiple local services where auth cookies originate from different domains, you need to consider using a server-side proxy or unifying under a single domain.
References
Loading...