Root Cause, zweifach:
1. proxy.ts lag im Projekt-Root statt unter src/ (wo app/ tatsaechlich
liegt). Next.js hat die Datei dadurch nie erkannt - ueberprueft via
Build-Output ("Proxy (Middleware)" fehlte komplett) und via
routes-manifest.json. Das betraf nicht nur die neuen
Security-Header, sondern auch die schon laenger bestehende
Login-Redirect-Logik, die dadurch vermutlich nie serverseitig
gegriffen hat - vorher unbemerkt, weil Client-seitige Auth-Checks
das kaschiert haben.
2. Die CSP (mit dynamischem connect-src aus API_URL) lag in
next.config.ts's headers() - die wird beim Docker-Build EINMAL
aufgeloest und ins Standalone-Output eingefroren, nicht bei jedem
Container-Start neu gelesen, wie im Code-Kommentar faelschlich
behauptet. Jedes Deployment bekam dadurch permanent
"connect-src http://localhost:3001" (den Fallback, da API_URL beim
Build nicht gesetzt ist) - unabhaengig vom tatsaechlich im Pod
gesetzten API_URL. Jede Anfrage vom Frontend ans Backend (Login,
SSO-Status, Herkunftsseite) wurde dadurch von jedem Browser
CSP-blockiert.
Fix: CSP + Security-Header ziehen nach proxy.ts (jetzt korrekt unter
src/) um - Proxy laeuft mit Node.js-Runtime frisch bei jeder Anfrage,
liest process.env.API_URL also korrekt zur Laufzeit. next.config.ts
behaelt nur noch die statische sw.js-Cache-Control-Regel.
Lokal end-to-end verifiziert: Build zeigt jetzt "ƒ Proxy (Middleware)"
(vorher komplett abwesend), CSP-Header zeigt nach Server-Start einen
distinct getesteten API_URL-Wert korrekt an (nicht mehr den
Localhost-Fallback), und ein echter Login-Klick im Browser schickt die
Anfrage jetzt an die richtige, zur Laufzeit gesetzte Backend-Origin.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
30 lines
1.3 KiB
TypeScript
30 lines
1.3 KiB
TypeScript
import type { NextConfig } from "next";
|
|
|
|
// Security headers (CSP, X-Frame-Options, etc.) live in proxy.ts, not here.
|
|
// This file's headers() is resolved once at build time and frozen into the
|
|
// standalone output - fine for a static value like the sw.js rule below, but
|
|
// wrong for the CSP's connect-src, which needs the container's actual
|
|
// runtime API_URL. That mistake shipped a permanently-wrong connect-src
|
|
// (build-time env, if any, or the localhost fallback) to every environment
|
|
// regardless of the real deployed API_URL, silently CSP-blocking every API
|
|
// call including login. Proxy runs fresh on every request and reads env
|
|
// correctly - see proxy.ts for the real header logic.
|
|
const nextConfig: NextConfig = {
|
|
output: "standalone",
|
|
async headers() {
|
|
return [
|
|
{
|
|
// Browsers are supposed to bypass HTTP cache when checking for a new
|
|
// service worker, but that's not reliably honored everywhere - an
|
|
// explicit no-cache header here is the only way to guarantee a sw.js
|
|
// fix actually reaches already-open tabs promptly after a deploy,
|
|
// instead of possibly sitting cached for hours.
|
|
source: "/sw.js",
|
|
headers: [{ key: "Cache-Control", value: "no-cache, no-store, must-revalidate" }],
|
|
},
|
|
];
|
|
},
|
|
};
|
|
|
|
export default nextConfig;
|