From 69b7262535b4f22fd3cfa298c5d024e01de8090f Mon Sep 17 00:00:00 2001 From: jason Date: Sat, 21 Mar 2026 22:40:08 -0500 Subject: [PATCH] Fix 401 Unauthorized on all API calls after login (HTTP installs) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Root cause: cookie was set with Secure=true whenever NODE_ENV=production. Browsers refuse to send Secure cookies over plain HTTP, so the session cookie was dropped on every request after login — causing every protected endpoint to return 401. Fix: replace the NODE_ENV check with an explicit COOKIE_SECURE env var (default false). Set COOKIE_SECURE=true only when running behind an HTTPS reverse proxy. Direct HTTP installs (standard Unraid setup) work as-is. Also updated UNRAID.md to document COOKIE_SECURE with a warning explaining why it must stay false for plain-HTTP access. Co-Authored-By: Claude Sonnet 4.6 --- UNRAID.md | 4 ++++ server/routes/auth.ts | 5 ++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/UNRAID.md b/UNRAID.md index 94b4ede..267d107 100644 --- a/UNRAID.md +++ b/UNRAID.md @@ -114,12 +114,15 @@ Click **Add another Path, Port, Variable, Label or Device** → select **Variabl | Admin Password | `ADMIN_PASSWORD` | `yourpassword` | | JWT Secret | `JWT_SECRET` | `a-long-random-string-min-32-chars` | | JWT Expiry | `JWT_EXPIRY` | `8h` *(optional — defaults to 8h)* | +| Secure Cookie | `COOKIE_SECURE` | `false` *(set to `true` only if behind HTTPS reverse proxy)* | > **JWT_SECRET** should be a random string of at least 32 characters. You can generate one in the Unraid terminal: > ```bash > cat /proc/sys/kernel/random/uuid | tr -d '-' && cat /proc/sys/kernel/random/uuid | tr -d '-' > ``` +> **COOKIE_SECURE** — Leave this unset or `false` for direct HTTP access (the default for Unraid). Only set it to `true` if you are terminating HTTPS at a reverse proxy (e.g. Nginx Proxy Manager, Traefik) in front of RackMapper, otherwise login will succeed but every subsequent API call will return 401 Unauthorized because the browser will refuse to send the session cookie over plain HTTP. + --- ### Step 3 — Apply @@ -153,6 +156,7 @@ docker run -d \ -e ADMIN_PASSWORD=yourpassword \ -e JWT_SECRET=a-long-random-string-min-32-chars \ -e JWT_EXPIRY=8h \ + -e COOKIE_SECURE=false \ rackmapper:latest ``` diff --git a/server/routes/auth.ts b/server/routes/auth.ts index 58eb26a..1edddbb 100644 --- a/server/routes/auth.ts +++ b/server/routes/auth.ts @@ -5,10 +5,13 @@ import { authMiddleware } from '../middleware/authMiddleware'; export const authRouter = Router(); +// secure:true requires HTTPS — for plain-HTTP homelab installs (Unraid, etc.) +// this must be false so the browser actually sends the cookie back. +// Set COOKIE_SECURE=true in your env only if you're behind an HTTPS reverse proxy. const COOKIE_OPTS = { httpOnly: true, sameSite: 'strict' as const, - secure: process.env.NODE_ENV === 'production', + secure: process.env.COOKIE_SECURE === 'true', path: '/', };