BUG: KI-Chat-Stream 403 'Stream failed: 403' und Wiki-Speichern 403 nach Seiten-Reload (CSRF-Token fehlt) #351

Closed
opened 2026-08-27 09:02:12 +00:00 by Leopoldadmin · 1 comment
Owner

Symptome

  1. Chat mit KI: Stream failed: 403 — Chat nicht möglich.
  2. Wiki: Beitrag speichern nicht möglich (403).

Ursachen (verifiziert im Code)

  1. frontend/src/api/ai.ts streamChat() liest sessionStorage.getItem('leocrm_csrf_token') — dieser Key wird nirgends geschrieben → Request geht ohne X-CSRF-Token raus → CSRFMiddleware antwortet 403 csrf_missing_token. Betrifft den Chat immer.
  2. Der gemeinsame apiClient hält den Token nur in einer In-Memory-Variablen, die nur beim Login gesetzt wird. Nach Seiten-Reload stellt useCurrentUser (/auth/me) ihn nicht wieder her, weil /auth/me den Token nicht liefert → alle Mutationen (Wiki-Save PATCH/POST u.a.) scheitern nach jedem Reload mit 403.

Fix (in Arbeit)

  • Backend: /auth/me liefert csrf_token aus der Session zurück.
  • Frontend: useCurrentUser stellt den Token beim Bootstrap wieder her; streamChat nutzt getCsrfToken() aus dem gemeinsamen Client statt des toten sessionStorage-Keys.
  • Regressionstests: pytest (test_me_returns_csrf_token_for_reload_restore) + Vitest (streamChat.test.ts).
## Symptome 1. Chat mit KI: `Stream failed: 403` — Chat nicht möglich. 2. Wiki: Beitrag speichern nicht möglich (403). ## Ursachen (verifiziert im Code) 1. `frontend/src/api/ai.ts streamChat()` liest `sessionStorage.getItem('leocrm_csrf_token')` — dieser Key wird nirgends geschrieben → Request geht ohne `X-CSRF-Token` raus → CSRFMiddleware antwortet 403 `csrf_missing_token`. Betrifft den Chat immer. 2. Der gemeinsame apiClient hält den Token nur in einer In-Memory-Variablen, die nur beim Login gesetzt wird. Nach Seiten-Reload stellt `useCurrentUser` (`/auth/me`) ihn nicht wieder her, weil `/auth/me` den Token nicht liefert → alle Mutationen (Wiki-Save PATCH/POST u.a.) scheitern nach jedem Reload mit 403. ## Fix (in Arbeit) - Backend: `/auth/me` liefert `csrf_token` aus der Session zurück. - Frontend: `useCurrentUser` stellt den Token beim Bootstrap wieder her; `streamChat` nutzt `getCsrfToken()` aus dem gemeinsamen Client statt des toten sessionStorage-Keys. - Regressionstests: pytest (`test_me_returns_csrf_token_for_reload_restore`) + Vitest (`streamChat.test.ts`).
Leopoldadmin added the bughigh labels 2026-08-27 09:02:12 +00:00
Author
Owner

Gefixt in Commit ebf4b03 — deployed und live verifiziert (2026-08-27 11:15):

Fix

  1. Backend: /auth/me liefert jetzt csrf_token aus der Session (app/services/auth_service.py get_current_user_info)
  2. Frontend: useCurrentUser stellt den Token beim Seiten-Reload wieder her; streamChat nutzt getCsrfToken() aus dem gemeinsamen Client statt des nie geschriebenen sessionStorage-Keys

Verifikation (Live-Messung)

  • pytest tests/test_auth.py: 11/11 passed inkl. neuem Regressionstest test_me_returns_csrf_token_for_reload_restore
  • Vitest streamChat.test.ts: 2/2 passed (X-CSRF-Token-Header bewiesen)
  • tsc --noEmit: exit 0 · ruff: clean
  • Full Deploy via Coolify (h9h01xm0nn8d): finished, Health healthy (DB/Redis/Storage/Worker up), Alembic 0142 OK, RLS 109 OK
  • Produktions-Bundle index-BCYHvz1a.js: toter Key leocrm_csrf_token 0 Treffer = Fix live
**Gefixt in Commit `ebf4b03` — deployed und live verifiziert (2026-08-27 11:15):** ## Fix 1. **Backend:** `/auth/me` liefert jetzt `csrf_token` aus der Session (`app/services/auth_service.py get_current_user_info`) 2. **Frontend:** `useCurrentUser` stellt den Token beim Seiten-Reload wieder her; `streamChat` nutzt `getCsrfToken()` aus dem gemeinsamen Client statt des nie geschriebenen sessionStorage-Keys ## Verifikation (Live-Messung) - pytest tests/test_auth.py: **11/11 passed** inkl. neuem Regressionstest `test_me_returns_csrf_token_for_reload_restore` - Vitest `streamChat.test.ts`: **2/2 passed** (X-CSRF-Token-Header bewiesen) - tsc --noEmit: exit 0 · ruff: clean - Full Deploy via Coolify (h9h01xm0nn8d): finished, Health healthy (DB/Redis/Storage/Worker up), Alembic 0142 OK, RLS 109 OK - Produktions-Bundle `index-BCYHvz1a.js`: toter Key `leocrm_csrf_token` **0 Treffer** = Fix live
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Leopoldadmin/leocrm#351