[Auth] Déconnexion forcée quand la session expire (réaction client sur 401) #108
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Résumé
Une session qui a expiré n'a aucun effet visible tant qu'on ne recharge pas complètement l'app : le client ne réagit à aucun
401en cours d'usage. Sur l'app native (rarement redémarrée à froid, token persisté), la session paraît ne jamais finir.Contexte (trouvé en auditant le code, pas supposé)
apps/api/src/lib/jwt.tssigne avec{ expiresIn: env.JWT_EXPIRES_IN };apps/api/src/config/env.ts→JWT_EXPIRES_INdéfaut"7d";jwt.verify(même fichier) rejette un token expiré ;require-auth.tsmappe l'échec en401 NOT_AUTHENTICATED. CookiemaxAge= 7 j (auth.routes.ts). (À vérifier : la valeurJWT_EXPIRES_INréellement déployée.)tokenVersionexiste dans le payload et est re-vérifié à chaque requête (require-auth.ts) mais rien ne l'incrémente jamais (aucun endpoint « logout everywhere » / « change password »).apps/web/src/api/client.tsApiClient._request()— sur!response.ok,throw new ApiError(status, …), aucun traitement spécifique du 401 : pas d'intercepteur, pas d'auto-logout, pas de purge du token. Token écrit seulement danslogin()/signup(), purgé seulement danslogout()/deleteAccount(). Natif :capacitor-token-store.ts(@capacitor/preferences, cléauth_token, persiste au redémarrage).apiClient.me()au montage deAuthProvider(features/auth/AuthContext.tsx) l'attrape →setUser(null)→RequireAuthredirige. Un401de n'importe quel autre endroit ne fait que remonter une erreur locale de la feature ; l'UI connectée reste affichée.Contenu attendu
Le client doit réagir à une session invalide/expirée : un handler
401central dansApiClient._request()qui, sur401 NOT_AUTHENTICATED, purge le token store, réinitialise l'état d'auth et redirige vers/login. Conserver la durée de vie 7 j.ApiClientétant agnostique du framework (pas deuseNavigate), motif : exposer un callbackonUnauthorizedqueAuthProviderenregistre au montage.Optionnel (hors périmètre strict) : brancher enfin
tokenVersionpour un vrai « déconnecter partout ».Couverture : Cypress avec un
cy.interceptrenvoyant401en cours de session → assert redirection/login+ état auth vidé.Dépendances
Aucune.