Files
MaksTinyWorkshop 9b7af9f1b0 Refonte Structure
2026-03-25 08:34:19 +01:00

4.3 KiB

Frontend — Risques & vigilance : Auth

Extrait de la base de connaissance Lead_tech. Voir knowledge/frontend/risques/README.md pour l'index complet.


Auth côté client (mauvaise séparation des responsabilités)

Risques

  • Le front "décide" des permissions au lieu d'appliquer un contrat backend
  • Affichage d'actions interdites / fuite d'informations dans l'UI
  • Tokens stockés de façon dangereuse (XSS)

Symptômes

  • Différences entre "ce que l'UI permet" et "ce que l'API accepte"
  • Bugs "ça marche chez moi" selon sessions/rôles
  • Incohérences sur refresh / multi-tab

Bonnes pratiques / mitigations

  • Le backend reste source de vérité (authz)
  • Cacher l'UI ≠ sécuriser : toujours sécuriser côté API
  • Stockage tokens : privilégier cookies httpOnly si modèle adapté
  • Gérer proprement expiration/refresh + révocation

Contexte technique

  • Observé : (à compléter)
  • Stack : (à préciser)

Loading infini sur écran gated par droits distants

Risques

  • Un écran protégé reste bloqué dans un faux loading après une erreur de chargement des entitlements
  • Un effet relance automatiquement la récupération en boucle sans action utilisateur
  • L'utilisateur ne voit ni état d'erreur ni issue de sortie claire

Symptômes

  • Spinner infini sur un écran soumis à permissions distantes
  • entitlements ou autorisations laissés à null après erreur
  • useEffect ou logique d'entrée qui retrigger le fetch à chaque rendu

Bonnes pratiques / mitigations

  • Distinguer explicitement loading, error, ready
  • Ne pas réutiliser null comme état ambigu "pas encore chargé" et "chargement en erreur"
  • Bloquer les retries automatiques en boucle après erreur
  • Réautoriser un retry seulement via action utilisateur explicite ou nouvelle condition d'entrée
  • Contexte technique : React Native / Expo / store d'entitlements — 10-03-2026

Bouton OAuth présent mais handler vide après refacto UI

Risques

  • L'OAuth est silencieusement cassé sur le nouvel écran — zéro erreur au démarrage, zéro crash
  • L'AC "toutes les fonctionnalités préservées" peut être coché alors que le bouton est mort

Symptômes

  • <Button title="Google" onPress={() => {}} /> — handler vide après copie depuis un ancien écran
  • OAuth fonctionnel sur l'écran précédent (welcome.tsx) mais absent sur le nouvel écran refactorisé

Bonnes pratiques / mitigations

  • Toute refacto UI qui introduit un bouton OAuth doit brancher le hook existant (useGoogleAuth(onSuccess))
  • Si la story exclut explicitement la fonctionnalité : soit le bouton n'apparaît pas, soit disabled avec un label explicite ("bientôt disponible")
  • Checklist review : chercher onPress={() => {}} sur tous les boutons OAuth dans les écrans refactorisés
  • Contexte technique : Expo Router / React Native — app-alexandrie story 0.3, 19-03-2026

Guard de rôle via return conditionnel dans le render (flash UX)

Risques

  • if (user?.role !== 'ADMIN') return <AccessDenied /> directement dans le corps du composant : pendant le chargement du store auth, user est null, ce qui déclenche un affichage momentané de l'écran "Accès refusé" avant le re-render
  • UX instable : flash visible, potentiellement suivi d'une boucle de re-render

Symptômes

  • L'écran "Accès refusé" clignote brièvement au montage avant d'afficher le bon contenu
  • Bug reproductible uniquement au chargement initial ou après un reload

Bonnes pratiques / mitigations

// ❌ Anti-pattern — flash si user === null au montage
if (user?.role !== 'ADMIN') return <AccessDenied />;

// ✅ Pattern correct — useEffect + rendu vide pendant chargement
useEffect(() => {
  if (user !== null && user.role !== 'ADMIN') {
    router.replace('/(tabs)');
  }
}, [user, router]);

if (user === null || user.role !== 'ADMIN') return <View />;
  • Règle : tout guard de rôle dans un composant React Native doit utiliser useEffect + redirect + rendu vide, jamais un return conditionnel direct

  • Contexte technique : React Native / Expo Router / Zustand auth — app-alexandrie 24-03-2026