fix(web-ui): forward X-Forwarded-Proto from outer proxy so mam-api emits Set-Cookie
This is the real cause of the login loop. mam-api sets its session cookie
with Secure=true (production config). express-session refuses to emit a
Secure Set-Cookie unless req.secure is true. With `app.set('trust proxy')`
on, req.secure derives from X-Forwarded-Proto.
web-ui's nginx was unconditionally sending `X-Forwarded-Proto: $scheme`.
Inside the web-ui container nginx listens on port 80, so $scheme is always
"http" — regardless of whether the outer NPM proxy terminated TLS. mam-api
saw http, decided the connection was insecure, and silently dropped the
Set-Cookie from the login response. Login succeeded server-side (session
row landed in PG, last_login_at updated) but the browser never received a
cookie, so the very next /auth/me check came back 401 and AuthGate bounced
to the login screen. Infinite loop.
The previous Connection: "upgrade" → $connection_upgrade fix wasn't wrong
(the hardcode is a real latent bug worth fixing) — it just wasn't the
proximate cause.
Fix: a second `map` directive forwards the outer X-Forwarded-Proto through
when present, falling back to $scheme only when no proxy header exists (so
direct localhost curls still work). Both /api/ and /capture/ now send the
correct value upstream, mam-api sees https, req.secure is true, Set-Cookie
flows through, login works.
Verified by curling the existing direct-to-mam-api path: with X-Forwarded-
Proto: https on the request, Set-Cookie comes back; without it, no
Set-Cookie. That's the exact difference between web-ui-proxied and
direct-to-mam-api in our previous diagnostic curls.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
c24c6156dc
commit
ac7730195d
1 changed files with 18 additions and 9 deletions
|
|
@ -1,16 +1,25 @@
|
|||
# Map for proper WebSocket upgrade handling on the proxied locations below.
|
||||
# Without this, hardcoding `proxy_set_header Connection "upgrade"` puts nginx
|
||||
# into tunnel-mode for every request — which silently drops response headers
|
||||
# including Set-Cookie. That broke session-cookie auth on /api/v1/auth/login:
|
||||
# mam-api was issuing the cookie, web-ui's proxy was eating it before it
|
||||
# reached the browser. With this map, Connection is only set to "upgrade"
|
||||
# when the client actually requested an Upgrade (real WebSocket); otherwise
|
||||
# it's "close" and the response flows through normally.
|
||||
# Hardcoding `proxy_set_header Connection "upgrade"` puts nginx into tunnel-
|
||||
# mode for every request, which has caused subtle bugs in the past. This
|
||||
# variant only sets Connection: upgrade when the client actually requested
|
||||
# an Upgrade (real WebSocket); otherwise it's "close".
|
||||
map $http_upgrade $connection_upgrade {
|
||||
default upgrade;
|
||||
'' close;
|
||||
}
|
||||
|
||||
# Forward the outer X-Forwarded-Proto when present; fall back to $scheme.
|
||||
# THIS IS WHY LOGIN WAS LOOPING: web-ui listens on port 80 inside the
|
||||
# container, so $scheme is always "http". With `proxy_set_header
|
||||
# X-Forwarded-Proto $scheme;`, mam-api saw http, decided req.secure=false,
|
||||
# and (because cookie.secure=true in production) silently refused to emit
|
||||
# the Set-Cookie at all. NPM correctly sends X-Forwarded-Proto: https on
|
||||
# the outer request — we just have to pass it through to mam-api.
|
||||
map $http_x_forwarded_proto $proxied_x_forwarded_proto {
|
||||
default $http_x_forwarded_proto;
|
||||
'' $scheme;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name _;
|
||||
|
|
@ -71,7 +80,7 @@ server {
|
|||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-Proto $proxied_x_forwarded_proto;
|
||||
# Preserve Content-Type so multer receives the full multipart boundary (#74)
|
||||
proxy_set_header Content-Type $content_type;
|
||||
proxy_buffering off;
|
||||
|
|
@ -91,7 +100,7 @@ server {
|
|||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-Proto $proxied_x_forwarded_proto;
|
||||
proxy_buffering off;
|
||||
proxy_request_buffering off;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue