53 lines
3.2 KiB
Markdown
53 lines
3.2 KiB
Markdown
# 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 `KeycloakAuthService` pour `FlutterSecureStorage` :
|
||
- Android : `AndroidOptions(encryptedSharedPreferences: true)`
|
||
- iOS : `IOSOptions(accessibility: KeychainAccessibility.first_unlock_this_device)`
|
||
|
||
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_token` puis `keycloak_webview_access_token` ; KeycloakAuthService écrit bien dans `keycloak_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.
|