Problem
JWT access tokens expire after 1 hour (token_lifetime_seconds = 3600 in zndraw_auth/settings.py). There is no refresh token mechanism — when the token expires, the frontend 401 interceptor silently downgrades the user to a guest session instead of re-authenticating them.
Impact: Every registered user loses their authenticated identity after 1 hour and sees "Session expired — reconnected as guest". They must manually re-login.
Current flow
- User logs in → receives a single JWT (access token, 1h lifetime)
- Token expires → REST calls return 401
- Axios interceptor catches 401 → calls
acquireToken() → falls back to guest login
- User is now a guest — no attempt to refresh the original session
Same issue affects Socket.IO reconnects and CLI token resolution.
Expected flow
- User logs in → receives access token (short-lived, e.g. 15 min) + refresh token (long-lived, e.g. 7 days, httpOnly cookie)
- Access token expires → 401 on REST call
- Interceptor calls a
/v1/auth/jwt/refresh endpoint with the refresh token → gets a new access token
- Original request is retried transparently — user stays authenticated
- Only when the refresh token itself expires does the user need to re-login
Key files
src/zndraw_auth/settings.py:32 — token_lifetime_seconds = 3600
src/zndraw_auth/users.py:98-105 — JWTStrategy (no refresh support)
frontend/src/myapi/client.ts:115-141 — 401 interceptor (falls back to guest)
frontend/src/utils/auth.ts:155-176 — acquireToken() (no refresh, just guest fallback)
Notes
fastapi-users supports refresh tokens via a separate transport/strategy — this should be leveraged rather than building from scratch
- The refresh token should be stored as an httpOnly cookie (not localStorage) to limit XSS exposure
- Guest users are less affected since they just get a new guest session, but registered users lose room ownership, permissions, etc.
Problem
JWT access tokens expire after 1 hour (
token_lifetime_seconds = 3600inzndraw_auth/settings.py). There is no refresh token mechanism — when the token expires, the frontend 401 interceptor silently downgrades the user to a guest session instead of re-authenticating them.Impact: Every registered user loses their authenticated identity after 1 hour and sees "Session expired — reconnected as guest". They must manually re-login.
Current flow
acquireToken()→ falls back to guest loginSame issue affects Socket.IO reconnects and CLI token resolution.
Expected flow
/v1/auth/jwt/refreshendpoint with the refresh token → gets a new access tokenKey files
src/zndraw_auth/settings.py:32—token_lifetime_seconds = 3600src/zndraw_auth/users.py:98-105—JWTStrategy(no refresh support)frontend/src/myapi/client.ts:115-141— 401 interceptor (falls back to guest)frontend/src/utils/auth.ts:155-176—acquireToken()(no refresh, just guest fallback)Notes
fastapi-userssupports refresh tokens via a separate transport/strategy — this should be leveraged rather than building from scratch