---
name: project_login_loop_rootcause
description: "Login-Loop lokal — Ursachen + Fix (gewaltiger Zeitfresser, nicht wiederholen)"
metadata: 
  node_type: memory
  type: project
  originSessionId: bcf0637c-def5-4024-b8c6-e8be02a43c4f
---

Der lokale Login-Loop (2026-06-02, riesiger Zeitfresser) hatte **mehrere überlagerte** Ursachen:

1. **Kern:** Der PWA-Service-Worker (`navigateFallback`/`NavigationRoute`) lieferte die gecachte App-Shell für den OIDC-Callback `/?code` aus (NavigationRoute ist VOR den runtimeCaching-Routen registriert). → BE sah den Code nie → `/auth/me` 401 → zurück zum Login → Loop. Bypass-for-network (SW aus) = sofort weg → eindeutiger SW-Beweis.
2. **Alter SW klebte:** loopte so schnell, dass das Auto-Update nicht durchkam → einmaliges Unregister/Clear nötig.
3. **Cookie:** BE-Build via `nx serve` nutzt `--node-env=production` → `secure: process.env.NODE_ENV==='production'` war lokal **true** → Secure-Cookie über http unzuverlässig.

**Fix (committet):** SW auf **injectManifest** umgestellt (`apps/plato-customer-fe/src/sw.ts`, lesbar) mit Callback NetworkOnly + `navigateFallbackDenylist: [...,/[?&]code=/]`; Cookie `secure:'auto'` (mit `trust proxy`); `ensureLoggedIn` offline-tolerant; `skipWaiting`/`clientsClaim`/`cleanupOutdatedCaches` → Deploys lösen den SW selbst ab.

**Lokales Re-Login nach BE-Neustart** ist erwartbar (MemoryStore); Prod nutzt Postgres-Sessions. Session-Store-Wechsel lokal: bewusst offen gelassen.

**Lehre fürs nächste Mal:** bei SW/Auth-Loop SOFORT Fakten holen — generierten `dist/sw.js` (Routen-Reihenfolge) ansehen + echtes BE-Log; nicht raten. Siehe [[feedback_evidence_first]], [[project_pwa_sw_auth_bypass]].
