Skip to main content

CORS & cookies

CORS preflight failures

Symptoms: browser console shows Access to fetch ... blocked by CORS policy. The request never reaches the server.

The marketplace CORS config:

app.enableCors({
origin: config.frontendUrl.split(',').map(s => s.trim()),
credentials: true,
});

Steps:

  1. Verify FRONTEND_URL matches your origin exactly. http://localhost:8080http://localhost:8081. https://app.fleapo.aihttps://www.app.fleapo.ai.
  2. Make sure you're not using *. credentials: true plus wildcard origin is forbidden by every modern browser. CORS preflight will fail silently.
  3. For multiple frontends, comma-separate: FRONTEND_URL=https://marketplace.fleapo.ai,https://staging.marketplace.fleapo.ai. The middleware splits and trims.

Restart the backend after any CORS env change.

Cookies not being sent

Symptoms: backend says "not signed in" even though you just signed in.

  1. credentials: 'include' must be on every fetch. The generated client handles this; if you write a raw fetch, add it.
  2. Cookie attributes:
    • Same-origin → SameSite=Lax is fine.
    • Cross-origin → MUST be SameSite=None; Secure. Secure requires HTTPS (localhost is exempt in modern Chrome).
  3. HttpOnly is fine — cookies still travel cross-origin if SameSite allows.
  4. Domain attribute — better-auth uses the default (same as request host). Don't override.

DevTools → Network → response → Set-Cookie header should be present. Application → Cookies should show it after the response.

If the header is there but the cookie isn't stored:

  • Wrong Domain attribute.
  • SameSite=Strict blocking cross-site.
  • Secure set but request was HTTP.

DevTools → Application → Cookies confirms it's stored. Network shows the next request doesn't include it.

  • Cross-origin? Check SameSite.
  • Subdomain mismatch? app.example.com cookie won't be sent to api.other.com.
  • Browser extension blocking it? Test in incognito.

"401 on /api/auth/get-session after redirect"

Classic OAuth callback scenario. The browser redirected from marketplace → agent backend. Agent backend's response set a session cookie, but the next request from the agent frontend doesn't include it.

  • Agent backend's cookie config must be SameSite=None; Secure because the frontend (app.my-agent.com) and backend (api.my-agent.com) are cross-origin.
  • Both must be HTTPS in production.

Local HTTPS for testing

When testing cross-origin with SameSite=None locally:

  • Modern Chrome accepts Secure cookies on localhost. Other browsers may not.
  • Use mkcert to issue local certs if needed.
  • Or use Cloudflare Tunnel / ngrok to expose with HTTPS.

Wildcard subdomains

If you want every *.preview.example.com to be allowed, the marketplace doesn't support that out of the box. Options:

  • Add each preview origin explicitly (tedious).
  • Or modify the CORS config to use a regex predicate. Note that you'll lose the simple FRONTEND_URL env-var contract.

Debugging tool

curl with verbose:

curl -v -b cookies.txt -H "Origin: http://localhost:8080" \
http://localhost:3000/api/auth/get-session

Inspect Access-Control-Allow-Origin, Access-Control-Allow-Credentials headers in the response.