2026-07-22 · 7 min
Rotation des refresh tokens en FastAPI avec détection de vol (ce que les tutos zappent)
La plupart des tutos JWT s’arrêtent à « voici comment émettre un token ». Voici comment faire tourner les refresh tokens, détecter le vol et révoquer toute une famille — avec les patterns FastAPI exacts.
La plupart des tutos d’auth FastAPI s’arrêtent à « voici comment signer un JWT » et zappent les parties qui font mal en production. Voici le raisonnement derrière une couche d’auth durcie — la même que celle livrée dans SecureLaunch. Le contenu tient debout tout seul ; prenez ce qui vous sert.
1. Choisir PyJWT, et verrouiller l’algorithme
python-jose a un historique de CVE chaotique et une maintenance irrégulière. PyJWT est plus petit, activement maintenu, et suffit largement. Deux choses non négociables au décodage :
- Épingler l’algorithme sur une liste fermée — passer
algorithms=["HS256"]et ne jamais faire confiance au champalgde l’en-tête entrant. C’est le piège classique de la confusion d’algorithme. - Exiger les claims dont vous dépendez, et vérifier un claim
typemaison pour qu’un access token ne puisse jamais être rejoué là où un refresh token est attendu.
2. Les refresh tokens doivent être opaques, pas des JWT
L’idée centrale que la plupart des tutos ratent : un JWT stateless ne peut pas être « dé-émis ». Si votre refresh token est un JWT, vous ne pouvez pas le révoquer — seulement attendre son expiration. Les refresh tokens doivent donc être des chaînes aléatoires opaques, stockées hachées (SHA-256), avec une vraie ligne en base.
- Access tokens : JWT courts (15 min).
- Refresh tokens : opaques, 256 bits, stockés en hash SHA-256, durée 30 jours.
Parce que le refresh token vit en base, la rotation et la révocation deviennent de vraies opérations plutôt qu’un vœu pieux.
3. Rotation + détection de réutilisation = détection de vol
À chaque refresh, l’ancien token est retiré et un nouveau émis. Le point important : si un token déjà utilisé réapparaît, on révoque toute la famille de tokens. Un refresh token rejoué est le signal le plus fort qu’un token a été volé — traitez-le comme une compromission, pas comme une erreur.
Concrètement : chaque token porte un identifiant de famille. Présenter un token déjà tourné déclenche une cascade qui invalide tous ses frères. L’utilisateur légitime est déconnecté une fois ; la copie de l’attaquant est morte.
4. Anti-énumération, honnêtement
Register et forgot-password renvoient un 202 constant ; login renvoie un unique 401 avec une vérification de hash factice pour égaliser le timing. Soyez honnête sur le compromis : dès que vous ajoutez un verrou par compte, un 429 sur un compte verrouillé (donc existant) versus un 401 sur un inconnu devient un oracle d’existence. Pas de repas gratuit — on l’arbitre contre le rate-limit par IP, et on le documente.
5. Mots de passe : argon2id, pas bcrypt via passlib
passlib est de fait non maintenu, et bcrypt tronque silencieusement les mots de passe à 72 octets — deux longs mots de passe différents peuvent donc entrer en collision. argon2id (via argon2-cffi) est la recommandation OWASP actuelle. Enrobez-le pour un rehash-on-verify automatique quand les paramètres changent, et imposez une politique 12–128 caractères sans troncature.
Le constat qui dérange
Rien de tout cela n’est exotique — c’est juste les 20 % de l’auth que les tutos laissent « en exercice au lecteur », et c’est exactement là que les SaaS early-stage se font trouer. Vous pouvez l’écrire vous-même en un week-end ; la valeur est de réussir chacun de ces détails et de les faire vérifier. Cette vérification — une revue adversariale écrite plus un audit OWASP ASVS L1 — c’est ce que SecureLaunch vend réellement.