docs: clarify AUTH_COOKIE_DOMAIN usage for cross-subdomain authentication and update related documentation

This commit is contained in:
Rotimi Best
2026-03-11 15:52:04 +01:00
parent 1bf0581869
commit c5c65b96d7
6 changed files with 11 additions and 26 deletions
+2 -2
View File
@@ -82,8 +82,8 @@ OBJECT_STORAGE_MEDIA_PUBLIC_BASE_URL=http://localhost:9000/media
GOOGLE_CLIENT_ID= GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET= GOOGLE_CLIENT_SECRET=
# Cookie domain for auth. Optional for Docker (falls back to DASHBOARD_ORIGIN). # Cookie domain for auth. Set to your root domain (e.g. .yourdomain.com) when API and dashboard use different subdomains.
# For Railway: set to your dashboard domain (e.g. app.yourdomain.com) when API and dashboard use different subdomains. # Without this, auth cookies may not be set and login will fail.
AUTH_COOKIE_DOMAIN= AUTH_COOKIE_DOMAIN=
# Dashboard domain routing # Dashboard domain routing
@@ -19,7 +19,8 @@ export const getSessionData = async (cookies: Cookies): Promise<App.Locals | nul
console.log('locals', locals); console.log('locals', locals);
if (!locals) return null; if (!locals) return null;
locals.fromSessions = !!cookies.get('classroomio.session_data'); // This will always be true because if we don't have classroomio cookies, we won't be able to this line of code.
locals.fromSessions = true;
return locals; return locals;
} catch (error) { } catch (error) {
@@ -114,7 +114,7 @@ Use `./run-docker-full-stack.sh --no-minio` to exclude MinIO if you do not need
| Variable | Description | | Variable | Description |
|----------|-------------| |----------|-------------|
| `GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET` | Google OAuth | | `GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET` | Google OAuth |
| `AUTH_COOKIE_DOMAIN` | Railway: dashboard domain when API/dashboard use different subdomains. Docker: optional (falls back to `DASHBOARD_ORIGIN`) | | `AUTH_COOKIE_DOMAIN` | Root domain for cross-subdomain cookies (e.g. `.yourdomain.com`) |
| `PRIVATE_APP_HOST`, `PRIVATE_APP_SUBDOMAINS` | Multi-subdomain routing | | `PRIVATE_APP_HOST`, `PRIVATE_APP_SUBDOMAINS` | Multi-subdomain routing |
| `UNSPLASH_API_KEY` | Unsplash image search | | `UNSPLASH_API_KEY` | Unsplash image search |
| `LICENSE_KEY` | Enterprise features (SSO, token-auth, no-tracking) | | `LICENSE_KEY` | Enterprise features (SSO, token-auth, no-tracking) |
@@ -191,8 +191,8 @@ AUTH_BEARER_TOKEN="some-key"
PRIVATE_SERVER_KEY="same-key-for-api-and-dashboard" PRIVATE_SERVER_KEY="same-key-for-api-and-dashboard"
PUBLIC_IS_SELFHOSTED="true" PUBLIC_IS_SELFHOSTED="true"
# Required for auth cookies when API and dashboard use different subdomains — set to your dashboard domain, e.g. app.yourdomain.com # Required for auth cookies when API and dashboard use different subdomains — set to your root domain, e.g. yourdomain.com
AUTH_COOKIE_DOMAIN="app.yourdomain.com" AUTH_COOKIE_DOMAIN="yourdomain.com"
# Email (configure one) # Email (configure one)
SMTP_HOST= SMTP_HOST=
@@ -210,7 +210,7 @@ CLOUDFLARE_IMAGE_BUCKET_DOMAIN=
``` ```
<Callout type="warn" title="AUTH_COOKIE_DOMAIN (Railway)"> <Callout type="warn" title="AUTH_COOKIE_DOMAIN (Railway)">
When API and dashboard use different subdomains, set `AUTH_COOKIE_DOMAIN` to your dashboard domain (e.g. `app.yourdomain.com`). Without it, Better Auth cookies will not be set and login will fail. Docker self-hosting falls back to `DASHBOARD_ORIGIN` when this is absent. When API and dashboard use different subdomains, set `AUTH_COOKIE_DOMAIN` to your root domain (e.g. `yourdomain.com`). Without it, Better Auth cookies will not be set and login will fail.
</Callout> </Callout>
Optional: add `GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET` for OAuth, `UNSPLASH_API_KEY` for image search, or `LICENSE_KEY` for enterprise features. Optional: add `GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET` for OAuth, `UNSPLASH_API_KEY` for image search, or `LICENSE_KEY` for enterprise features.
-1
View File
@@ -109,7 +109,6 @@ services:
PUBLIC_SERVER_URL: ${PUBLIC_SERVER_URL:-http://localhost:3081} PUBLIC_SERVER_URL: ${PUBLIC_SERVER_URL:-http://localhost:3081}
TRUSTED_ORIGINS: ${TRUSTED_ORIGINS:-http://localhost:3082} TRUSTED_ORIGINS: ${TRUSTED_ORIGINS:-http://localhost:3082}
AUTH_COOKIE_DOMAIN: ${AUTH_COOKIE_DOMAIN:-} AUTH_COOKIE_DOMAIN: ${AUTH_COOKIE_DOMAIN:-}
DASHBOARD_ORIGIN: ${DASHBOARD_ORIGIN:-http://localhost:3082}
DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-postgres}@postgres:5432/${POSTGRES_DB:-classroomio} DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-postgres}@postgres:5432/${POSTGRES_DB:-classroomio}
PRIVATE_DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-postgres}@postgres:5432/${POSTGRES_DB:-classroomio} PRIVATE_DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-postgres}@postgres:5432/${POSTGRES_DB:-classroomio}
REDIS_URL: redis://redis:6379 REDIS_URL: redis://redis:6379
+1 -1
View File
@@ -26,7 +26,7 @@ All Docker services read from a single root `.env` file. See [`.env.example`](..
Key points: Key points:
- **Required:** `PUBLIC_SERVER_URL`, `TRUSTED_ORIGINS`, `BETTER_AUTH_SECRET`, `PUBLIC_IS_SELFHOSTED=true`, `ALLOWED_EXTERNAL_DOMAINS`, `DASHBOARD_ORIGIN`. - **Required:** `PUBLIC_SERVER_URL`, `TRUSTED_ORIGINS`, `BETTER_AUTH_SECRET`, `PUBLIC_IS_SELFHOSTED=true`, `ALLOWED_EXTERNAL_DOMAINS`, `DASHBOARD_ORIGIN`.
- **Auth cookies:** When `AUTH_COOKIE_DOMAIN` is absent, the API falls back to `DASHBOARD_ORIGIN` (hostname). - **Auth cookies:** Set `AUTH_COOKIE_DOMAIN` to your root domain (e.g. `.yourdomain.com`) when API and dashboard use different subdomains. Without it, auth cookies may not be set and login will fail.
- **Auto-generated:** `AUTH_BEARER_TOKEN`, `PRIVATE_SERVER_KEY` (by `./run-docker-full-stack.sh`). - **Auto-generated:** `AUTH_BEARER_TOKEN`, `PRIVATE_SERVER_KEY` (by `./run-docker-full-stack.sh`).
- **Auto-configured:** All `MINIO_*` / `OBJECT_STORAGE_*` vars (by the startup script). - **Auto-configured:** All `MINIO_*` / `OBJECT_STORAGE_*` vars (by the startup script).
- **Optional:** Email (SMTP or Zoho), Google OAuth, Unsplash, `LICENSE_KEY` (enterprise). - **Optional:** Email (SMTP or Zoho), Google OAuth, Unsplash, `LICENSE_KEY` (enterprise).
+2 -17
View File
@@ -1,8 +1,7 @@
const { const {
TRUSTED_ORIGINS: TRUSTED_ORIGINS_STRING, TRUSTED_ORIGINS: TRUSTED_ORIGINS_STRING,
PUBLIC_SERVER_URL, PUBLIC_SERVER_URL,
AUTH_COOKIE_DOMAIN: AUTH_COOKIE_DOMAIN_STRING, AUTH_COOKIE_DOMAIN: AUTH_COOKIE_DOMAIN_STRING
DASHBOARD_ORIGIN: DASHBOARD_ORIGIN_STRING
} = process.env; } = process.env;
const DEFAULT_TRUSTED_ORIGINS = [ const DEFAULT_TRUSTED_ORIGINS = [
@@ -31,18 +30,4 @@ export const TRUSTED_ORIGINS = TRUSTED_ORIGINS_STRING
export const BASE_URL = PUBLIC_SERVER_URL || 'http://localhost:3002'; export const BASE_URL = PUBLIC_SERVER_URL || 'http://localhost:3002';
function getAuthCookieDomain(): string | undefined { export const AUTH_COOKIE_DOMAIN = AUTH_COOKIE_DOMAIN_STRING?.trim() || undefined;
const explicit = AUTH_COOKIE_DOMAIN_STRING?.trim();
if (explicit) return explicit;
if (!DASHBOARD_ORIGIN_STRING?.trim()) return undefined;
try {
const url = new URL(DASHBOARD_ORIGIN_STRING.trim());
return url.hostname || undefined;
} catch {
return undefined;
}
}
export const AUTH_COOKIE_DOMAIN = getAuthCookieDomain();