E-mails de réinitialisation du mot de passe : confiance et délivrabilité

Créez un parcours de réinitialisation du mot de passe sécurisé : jetons à usage unique, expiration courte, pas d’énumération de comptes, modèle clair et confirmation.

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

  1. L’utilisateur saisit son adresse e-mail sur la page Mot de passe oublié.
  2. Votre application affiche toujours le même message, que le compte existe ou non.
  3. S’il existe, vous créez un jeton à usage unique et envoyez un lien de réinitialisation par e-mail.
  4. L’utilisateur ouvre le lien, choisit un nouveau mot de passe, et le jeton est consommé.
  5. 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.

Créer un compte Voir les tarifs