L’e-mail de réinitialisation du mot de passe est le passe-partout de votre produit. Quiconque peut le lire peut prendre le contrôle du compte : c’est pourquoi les attaquants le ciblent, et pourquoi les utilisateurs ont appris à s’en méfier.
Un bon parcours de réinitialisation doit être assez sûr pour résister à ces attaquants, et assez clair pour que les vrais utilisateurs lui fassent confiance en quelques secondes. Ce guide aborde les deux, du moment où quelqu’un clique sur « Mot de passe oublié ? » jusqu’à l’e-mail de confirmation après le changement.
Le parcours en un coup d’œil
- L’utilisateur saisit son adresse e-mail sur la page Mot de passe oublié.
- Votre application affiche toujours le même message, que le compte existe ou non.
- S’il existe, vous créez un jeton à usage unique et envoyez un lien de réinitialisation par e-mail.
- L’utilisateur ouvre le lien, choisit un nouveau mot de passe, et le jeton est consommé.
- Vous déconnectez les autres sessions de l’utilisateur et envoyez un e-mail « votre mot de passe a été modifié ».
Étape 1 : ne révélez pas qui a un compte
Une fois le formulaire envoyé, répondez toujours avec le même texte :
Si un compte existe pour ada@example.com, nous avons envoyé un lien pour réinitialiser votre mot de passe. Il expire dans 30 minutes.
Afficher à la place « Aucun compte associé à cette adresse » indique à quiconque possède une liste d’adresses exactement lesquelles utilisent votre produit. Gardez aussi un temps de réponse similaire : effectuez la recherche du compte et l’envoi de l’e-mail en arrière-plan, pour que la page ne réponde pas sensiblement plus vite pour les adresses inconnues.
Étape 2 : créez un jeton robuste à usage unique
Le jeton contenu dans le lien doit être long, aléatoire et impossible à deviner :
import { randomBytes, createHash } from 'node:crypto';
const token = randomBytes(32).toString('base64url'); // goes in the email
const tokenHash = createHash('sha256').update(token).digest('hex'); // goes in the database
await db.passwordResets.upsert({
userId: user.id,
tokenHash,
expiresAt: new Date(Date.now() + 30 * 60 * 1000), // 30 minutes
});
Les règles :
- Ne stockez qu’un hachage du jeton, pour qu’une fuite de la base de données ne distribue pas des liens de réinitialisation fonctionnels.
- Un seul jeton actif par utilisateur. En émettre un nouveau remplace l’ancien.
- Expiration courte : 15 à 60 minutes est la norme.
- Usage unique. Supprimez le jeton dès que le mot de passe a été modifié.
- Invalidez-le si l’utilisateur se connecte avec succès ou modifie son adresse e-mail entre-temps.
Étape 3 : envoyez l’e-mail immédiatement
L’utilisateur attend : envoyez dans la requête, pas dans une tâche groupée.
import os
import requests
def send_reset_email(user, token):
link = f"https://app.yourco.com/reset-password/{token}"
res = requests.post(
"https://backend.inbixio.com/api/send-email/",
headers={"X-API-Key": os.environ["INBIXIO_API_KEY"]},
json={
"to_email": user.email,
"subject": "Reset your YourApp password",
"message": render_reset_template(name=user.first_name, link=link, minutes=30),
},
timeout=10,
)
res.raise_for_status()
Envoyez-le depuis une adresse dédiée et authentifiée, comme security@yourco.com. Dans Inbixio, connectez cette boîte mail comme serveur e-mail à part entière et attribuez au service d’authentification une clé API qui lui est rattachée, pour que les e-mails de réinitialisation proviennent de l’adresse attendue par les utilisateurs. Si vous supprimez un jour ce serveur, rattachez à nouveau la clé. Consultez la sécurité des clés API pour la mise en place.
Étape 4 : rédigez un e-mail digne de confiance
Les e-mails de phishing imitent les réinitialisations de mot de passe plus que tout autre message. Rendez le vôtre reconnaissable entre tous :
- Objet : simple et précis, par ex. « Reset your YourApp password ». Pas d’urgence, pas de points d’exclamation.
- Un seul bouton clair, plus le lien complet en texte pour les clients qui bloquent les boutons.
- L’expiration : « Ce lien expire dans 30 minutes. »
- Le contexte : quand la demande a été faite et, si vous en disposez, depuis quel navigateur ou quelle ville.
- Quoi faire si ce n’était pas eux : « Si vous n’avez pas demandé à réinitialiser votre mot de passe, vous pouvez ignorer cet e-mail. Votre mot de passe ne changera pas. »
- Aucun autre lien, image ou promotion. Moins il y a de liens, plus l’e-mail est facile à vérifier.
<div style="font-family:system-ui,sans-serif;max-width:520px;margin:auto;color:#111;line-height:1.5">
<p>Hi Ada,</p>
<p>We received a request to reset the password for your YourApp account.</p>
<p style="margin:28px 0">
<a href="https://app.yourco.com/reset-password/TOKEN"
style="background:#584efe;color:#fff;padding:12px 20px;border-radius:8px;text-decoration:none;font-weight:600">
Choose a new password
</a>
</p>
<p>This link expires in 30 minutes and can only be used once.</p>
<p>If you didn't ask to reset your password, you can safely ignore this email.</p>
<p style="color:#666;font-size:13px">Button not working? Paste this link into your browser:<br>
https://app.yourco.com/reset-password/TOKEN</p>
</div>
Étape 5 : traitez le lien avec soin
Lorsque l’utilisateur ouvre le lien :
- Recherchez le hachage du jeton, vérifiez qu’il n’a pas expiré et affichez le formulaire « nouveau mot de passe ». Ne connectez pas encore l’utilisateur.
- Tenez le jeton à l’écart des requêtes tierces. Ajoutez
<meta name="referrer" content="no-referrer">à la page de réinitialisation et n’y chargez ni scripts d’analyse ni scripts publicitaires, pour que le jeton présent dans l’URL ne fuite pas via les en-têtes referrer. - À la validation, vérifiez le nouveau mot de passe au regard de vos règles, hachez-le avec un algorithme lent (bcrypt, scrypt ou Argon2), supprimez le jeton et déconnectez toutes les autres sessions.
Étape 6 : confirmez le changement
Envoyez toujours une courte confirmation après un changement de mot de passe :
Votre mot de passe YourApp a été modifié le 28 octobre à 14:32 UTC. Si c’était vous, vous n’avez rien d’autre à faire. Sinon, sécurisez votre compte sans attendre.
Cet e-mail est le signal d’alarme de l’utilisateur si quelqu’un d’autre a pris la main sur son compte : ne l’omettez jamais.
Assurez-vous qu’il arrive
Un e-mail de réinitialisation dans les spams, c’est un ticket de support. Avant le lancement :
- configurez SPF, DKIM et DMARC pour votre domaine d’envoi,
- testez avec des adresses Gmail et Outlook et vérifiez que les en-têtes indiquent PASS, et
- surveillez le taux de Failed Deliveries (échecs de livraison) sur votre tableau de bord Inbixio après le déploiement.
Checklist
- Même réponse pour les adresses existantes et inconnues
- Jeton aléatoire de 32 octets, seul son hachage est stocké
- Expiration de 15 à 60 minutes, usage unique, un seul jeton actif par utilisateur
- Envoi immédiat depuis un expéditeur dédié et authentifié
- Modèle clair : un bouton, le lien en clair, l’expiration, une ligne « ce n’était pas vous ? »
- Aucun script tiers sur la page de réinitialisation ; referrer désactivé
- Autres sessions déconnectées et e-mail de confirmation envoyé après le changement
Envoyez-le avec Inbixio
Connectez votre propre serveur SMTP, créez une clé API aux droits limités et envoyez depuis n’importe quel langage en une seule requête HTTPS.