SecureLaunch
← Tous les articles

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 :

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.

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.