3.2 KiB
3.2 KiB
Corrections structurées : 401 et token manquant sur les requêtes API
1. Diagnostic (symptômes observés)
- Logs :
DIO: Aucun token pour /api/membres,/api/cotisations/mes-cotisations/en-attente,/api/adhesions,/api/notifications/membre/... - Effet : Toutes les requêtes API (membres, cotisations, adhésions, notifications) reçoivent 401 Unauthorized.
- Constat : L’utilisateur est bien authentifié (log « Token rafraîchi avec succès », « Utilisateur authentifié: Membre MUKEFI »), mais le client HTTP n’envoie jamais le Bearer token.
2. Cause racine
Deux instances différentes de FlutterSecureStorage sont utilisées :
| Composant | Configuration stockage |
|---|---|
| KeycloakAuthService | FlutterSecureStorage(aOptions: AndroidOptions(encryptedSharedPreferences: true), iOptions: IOSOptions(...)) |
| DioClient | FlutterSecureStorage() (défaut) |
Sur Android, une configuration avec encryptedSharedPreferences: true et la configuration par défaut ne partagent pas le même espace de stockage. Les tokens écrits par Keycloak après login/refresh sont donc invisibles pour l’intercepteur Dio, qui lit un stockage vide → « Aucun token ».
3. Correction appliquée
3.1 Unifier la configuration du stockage (DioClient)
Fichier : lib/core/network/dio_client.dart
- Utiliser la même configuration que
KeycloakAuthServicepourFlutterSecureStorage:- Android :
AndroidOptions(encryptedSharedPreferences: true) - iOS :
IOSOptions(accessibility: KeychainAccessibility.first_unlock_this_device)
- Android :
Ainsi, lecture et écriture des clés keycloak_access_token, keycloak_refresh_token, etc. se font dans le même stockage que celui utilisé par l’auth.
3.2 Vérifications connexes (déjà en place)
- Clés : DioClient lit
keycloak_access_tokenpuiskeycloak_webview_access_token; KeycloakAuthService écrit bien danskeycloak_access_token(flux password) et dans le refresh Dio. - Log diagnostic : Le log « DIO: Auth token présent / Aucun token pour … » reste utile pour vérifier que le token est bien lu après correction.
4. Résumé des fichiers modifiés
| Fichier | Modification |
|---|---|
lib/core/network/dio_client.dart |
Utiliser un FlutterSecureStorage avec AndroidOptions(encryptedSharedPreferences: true) et IOSOptions(accessibility: KeychainAccessibility.first_unlock_this_device) (aligné sur KeycloakAuthService). |
lib/core/network/api_client.dart |
Idem : lire le token depuis le même type de stockage pour les modules DRY (Feed, Explore, etc.). |
5. Après correction
- Redémarrer l’app (full restart), se reconnecter si besoin.
- Ouvrir les écrans : Membres, Cotisations, Adhésions, Notifications.
- Dans les logs :
DIO: Auth token présent pour /api/...et plus de 401 sur ces endpoints (sous réserve que le backend accepte le JWT).
6. Évolution possible
- Centraliser la création du
FlutterSecureStorage« auth » dans un seul module (ex.lib/core/storage/ou config partagée) et l’injecter / l’utiliser à la fois dans KeycloakAuthService et DioClient pour éviter toute divergence future.