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

8.3 KiB

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)

{
  "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)

- 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)

- 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)

- 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)

- 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)

// 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