# Backend — Patterns : Auth > Extrait de la base de connaissance Lead_tech. Voir `knowledge/backend/patterns/README.md` pour l'index complet. --- ## Pattern : Format d'erreur API standardisé - Objectif : fournir des erreurs prévisibles, exploitables et cohérentes pour tous les clients. - Contexte : API consommée par front-end, automatisations ou intégrations externes. - Quand l'utiliser : dès qu'une API est exposée à autre chose qu'un usage interne trivial. - Quand l'éviter : jamais. - Avantage : - Debug plus rapide - UX maîtrisée côté client - Observabilité améliorée - Limites / vigilance : - Discipline requise pour éviter les formats ad hoc - Validé le : 25-01-2026 - Contexte technique : API HTTP agnostique ### Implémentation (exemple minimal) ```json { "error": { "code": "USER_NOT_FOUND", "message": "Utilisateur introuvable", "requestId": "abc-123" } } ``` ### Checklist - Codes HTTP cohérents (4xx / 5xx) - Codes d'erreur applicatifs stables - Message utilisateur non technique - requestId présent --- ## Pattern : Middleware de corrélation (requestId / traceId) - Objectif : relier chaque requête aux logs et erreurs associées. - Contexte : toute API ou service exposé. - Quand l'utiliser : systématiquement en production. - Quand l'éviter : jamais. - Avantage : - MTTR réduit drastiquement - Debug cross-services possible - Limites / vigilance : - Doit être propagé partout (logs, erreurs, appels sortants) - Validé le : 25-01-2026 - Contexte technique : Backend agnostique (HTTP) ### Implémentation (exemple minimal) ```txt - Générer un requestId à l'entrée si absent - Le propager dans le contexte de requête - L'inclure dans chaque log et réponse d'erreur ``` ### Checklist - requestId généré ou repris d'un header existant - Présent dans tous les logs - Présent dans les erreurs retournées --- ## Pattern : Anti-énumération sur endpoints auth liés à un email - Objectif : empêcher qu'un endpoint auth révèle si un compte existe, n'existe pas ou n'est pas éligible. - Contexte : reset de mot de passe, invitation, vérification de compte, login ou tout flux qui part d'un email utilisateur. - Quand l'utiliser : dès qu'une requête auth touche un identifiant de type email. - Quand l'éviter : jamais sur une surface exposée. - Avantage : - réduit la fuite d'information sur les comptes existants - homogénéise les réponses côté client - se combine bien avec les garde-fous anti-abus - Limites / vigilance : - ne protège pas seul contre le brute-force, à combiner avec du rate-limiting - les logs internes doivent conserver la vraie cause sans l'exposer au client - Validé le : 16-03-2026 - Contexte technique : Node.js / auth applicative / API HTTP ### Implémentation (exemple minimal) ```txt - retourner la même réponse HTTP 200 qu'un compte existe ou non - ne jamais distinguer "email inconnu", "email connu" ou "compte OAuth-only" dans la réponse - journaliser la cause réelle côté serveur - ajouter un rate-limiting basé sur email + IP ``` ### Checklist - Réponse client uniforme pour les cas compte connu/inconnu/non éligible - Aucune fuite d'existence dans le message ou le code d'erreur - Rate-limiting présent sur les endpoints exposés - Logs internes exploitables --- ## Pattern : Token à usage unique — génération, hash et invalidation atomique - Objectif : standardiser la création et la consommation de tokens sensibles sans stocker de secret brut en base. - Contexte : invitation, reset de mot de passe, vérification d'email, lien magique ou tout token one-shot. - Quand l'utiliser : pour tout token à usage unique transmis à l'utilisateur. - Quand l'éviter : sessions longues ou secrets devant être relus en clair côté serveur. - Avantage : - réduit l'impact d'une fuite de base - garde des tokens URL-safe - favorise une consommation atomique et réutilisable - Limites / vigilance : - la consommation doit rester atomique - la politique d'expiration doit être explicite - Validé le : 16-03-2026 - Contexte technique : Node.js `crypto` / Prisma / email ou URL signée ### Implémentation (exemple minimal) ```txt - générer le token avec `crypto.randomBytes(32).toString("base64url")` - stocker uniquement le hash SHA-256 du token en base - transmettre le token brut uniquement via URL ou email - recalculer le hash côté serveur lors de la consommation - invalider le token dans une transaction atomique après usage ``` ### Checklist - Token brut jamais persisté en base - Hash recalculé côté serveur pour la vérification - Expiration explicite - Invalidation atomique après consommation --- ## Pattern : Autorisation interne minimale sans RBAC complet - Objectif : sécuriser une capacité interne sensible sans ouvrir trop tôt un chantier RBAC complet. - Contexte : application avec peu de rôles, besoin ponctuel d'une capacité admin ou opérateur clairement identifiée. - Quand l'utiliser : quand une story métier demande un pouvoir interne limité mais réel. - Quand l'éviter : si les permissions deviennent nombreuses, hiérarchiques ou contextuelles. - Avantage : - sécurisation rapide et lisible d'une capacité sensible - source de vérité backend explicite - chemin d'évolution propre vers un RBAC plus complet - Limites / vigilance : - ne pas laisser proliférer des rôles ad hoc non gouvernés - ne remplace pas un vrai modèle de permissions si le domaine grossit - Validé le : 10-03-2026 - Contexte technique : NestJS / auth par session ou JWT / API métier interne ### Implémentation (exemple minimal) ```txt - introduire un enum de rôle minimal côté backend (ex. USER | ADMIN) - propager ce rôle dans la session ou le token d'auth - créer un décorateur + guard dédiés pour la capacité sensible - interdire les booléens front, emails hardcodés ou `if` dispersés dans les contrôleurs ``` ### Checklist - Le rôle vit dans la source de vérité backend - Le rôle est propagé dans le mécanisme d'auth existant - Les endpoints sensibles passent par un guard dédié - Aucun contrôle d'accès critique n'est piloté par le front - Le passage à RBAC reste possible sans casser le contrat existant --- ## Pattern : Opérations auth sensibles — atomiques, idempotentes et cohérentes - Objectif : garantir que les opérations multi-étapes auth (reset, logout, révocation) ne laissent jamais un état incohérent. - Contexte : tout flux auth qui combine plusieurs writes : hash de mot de passe, invalidation de token, suppression de session. - Quand l'utiliser : systématiquement sur toute opération qui touche plusieurs tables auth en séquence. - Quand l'éviter : opérations de lecture pure. - Avantage : - pas de token valide après reset de mot de passe si l'opération est interrompue - suppression de session idempotente (P2025 absorbé silencieusement) - comportement prévisible même en cas de retry ou de concurrence - Limites / vigilance : - `$transaction` Prisma ne couvre pas les effets de bord réseau (email, cookies) — ces étapes restent hors transaction - Validé le : 16-03-2026 - Contexte technique : Node.js / Prisma / auth par session ou token ### Implémentation (exemple minimal) ```typescript // consumePasswordReset — atomique dans une transaction await prisma.$transaction([ prisma.passwordResetToken.update({ where: { tokenHash }, data: { consumedAt: new Date() }, }), prisma.user.update({ where: { id: userId }, data: { passwordHash: newHash }, }), prisma.session.deleteMany({ where: { userId } }), ]); // Suppression de session — idempotente (P2025 absorbé) try { await prisma.session.delete({ where: { sessionToken } }); } catch (err) { if (err?.code !== 'P2025') throw err; // session déjà supprimée → OK } ``` ### Checklist - [ ] Toute opération hash + update + delete dans une `$transaction` - [ ] `P2025` absorbé silencieusement sur les suppressions de session - [ ] Effets de bord hors transaction documentés (cookie, email) - [ ] Tests couvrant le cas d'une session déjà expirée