Disons que votre équipe met en production un nouvel e-mail de réinitialisation de mot de passe. La QA valide en préproduction : le message apparaît, le lien fonctionne, le modèle est correct. Deux jours après la mise en ligne, le support a une file de tickets. Des gens avec des adresses Gmail disent que l'e-mail n'est jamais arrivé. Des gens dans quelques grandes entreprises disent qu'il est arrivé, mais que le lien était « déjà utilisé » dès le premier clic. Personne n'a modifié le code entre la préproduction et la production, et tous les tests passent encore.
Alors quelle adresse e-mail de test pour développeurs aurait permis de le voir ? Aucune seule. Un collecteur SMTP local convient au développement quotidien, le bac à sable de votre fournisseur ou un domaine de test que vous contrôlez convient aux tests automatisés, et une vraie boîte externe convient à la vérification manuelle que le courrier quitte votre environnement proche de la production et atteint le domaine d'un inconnu. Une boîte temporaire comme VookMail couvre ce dernier cas sans aucune configuration, car une adresse est prête au chargement de la page. Des comptes témoins chez les grands fournisseurs de messagerie couvrent ensuite la partie qu'aucune des autres ne voit. Le reste de ce guide porte sur le choix entre ces options, la lecture des échecs quand ils surviennent, et les vérifications qui ont leur place dans une mise en production.
Pourquoi cette réinitialisation est passée en préproduction
La préproduction et la production se ressemblent rarement autant que le schéma de déploiement le laisse croire, et l'e-mail révèle les différences plus que la plupart des fonctionnalités. Un message traverse votre application, une file d'attente, un fournisseur, le DNS, le serveur du destinataire et le client du destinataire. La préproduction peut utiliser une version différente de presque tous ces éléments.
Prenons le premier ticket, les utilisateurs de Gmail qui n'ont rien reçu. Supposons que la préproduction envoie via un sous-domaine du fournisseur authentifié il y a des mois, tandis que la production envoie depuis un nouveau domaine From introduit avec le changement de marque. Les consignes de Google pour les expéditeurs exigent que tous les expéditeurs s'authentifient avec SPF ou DKIM, et le tableau d'erreurs de Gmail mentionne 5.7.26 pour le courrier non authentifié. Une boîte QA interne sur votre propre domaine peut laisser passer le même message, puisque votre propre serveur peut faire confiance à votre propre relais. Le test ne pouvait jamais échouer.
Le second ticket, le lien « déjà utilisé », a une autre cause. Les passerelles de sécurité des entreprises ouvrent couramment les liens du courrier entrant pour les analyser avant que la personne ne les voie. Si votre lien consomme le jeton sur une simple requête GET, l'analyseur l'épuise, et l'employé clique sur un lien mort. Aucune de vos boîtes de préproduction ne fait tourner cet analyseur, sauf si votre propre entreprise en utilise un.
Ces deux bugs ne se voient pas du même endroit. L'un exige une vraie livraison vers un système récepteur que vous n'exploitez pas. L'autre exige un changement dans le comportement du lien, qu'une revue de code attraperait plus facilement qu'un test. C'est l'argument en faveur des tests par couches : chaque type d'adresse répond à une question et reste muet sur les autres.
| Ce qui diffère souvent entre préproduction et production | Ce que cela peut cacher |
|---|---|
Domaine d'envoi et adresse From | SPF et DKIM manquants ou mal alignés |
| Compte ou sous-compte du fournisseur | Mode bac à sable, limites d'envoi, une autre réputation d'IP |
| Destinataires | Domaines internes qui vous font confiance, et listes d'autorisation qui masquent les mauvaises adresses |
| Suivi des clics | Liens réécrits qui cassent, ou domaine de suivi sans certificat valide |
| Volume | Files d'attente et limites de débit qui ne mordent que sous charge |
| Listes de suppression | Adresses de production qui ont rebondi une fois et sont maintenant ignorées en silence |
| Réglages d'URL de base | Liens qui pointent vers le mauvais hôte |
Quelle adresse répond à quelle question
Voici les options, chacune avec la question à laquelle elle peut réellement répondre.
Un collecteur local : « qu'a produit mon application ? »
Un collecteur SMTP accepte tout ce que votre application envoie et l'affiche dans une page web sans rien livrer. Mailpit est un choix open source populaire. Par défaut, il écoute le SMTP sur le port 1025 et sert son interface web sur le port 8025 : vous pointez donc vos réglages de développement vers localhost:1025 et ouvrez http://localhost:8025. Ethereal de Nodemailer suit une idée proche, avec un faux service SMTP hébergé. Un collecteur est rapide et privé, et il vous laisse envoyer à n'importe quelle adresse sans aucun risque d'atteindre une vraie personne. Il ne dit rien non plus du DNS, de l'authentification ou du filtrage, puisque rien ne traverse internet.
Un utilitaire de test du framework : « mon code a-t-il demandé le bon courrier ? »
La plupart des frameworks savent enregistrer le courrier sortant en mémoire pendant une exécution de tests. Laravel a Mail::fake(), Django collecte les messages dans django.core.mail.outbox, et Rails a ActionMailer::Base.deliveries. Servez-vous-en pour vérifier qu'une tâche se déclenche une fois avec le bon destinataire et le bon jeton. C'est le retour le plus rapide possible, et cela teste encore moins le monde extérieur qu'un collecteur.
Le mode test d'un fournisseur : « mon intégration fonctionne-t-elle ? »
Les fournisseurs offrent ici différents types d'aide, et les différences comptent. Amazon SES a un simulateur de boîte e-mail avec des adresses comme success@simulator.amazonses.com, bounce@simulator.amazonses.com et complaint@simulator.amazonses.com, qui produisent ces résultats sans nuire à votre réputation. Un nouveau compte SES démarre aussi dans un bac à sable où il ne peut envoyer qu'à des adresses vérifiées. Le mode bac à sable de SendGrid, activé par mail_settings.sandbox_mode.enable, valide votre requête sans livrer. Postmark accepte le jeton POSTMARK_API_TEST dans le même but. Ces outils sont bons pour les erreurs d'API et pour les webhooks de rebond et de plainte, et ils ne montrent pas que le courrier a atteint quelqu'un. Consultez la documentation actuelle de votre fournisseur, car ces fonctions changent.
Un domaine de test à vous : « le parcours complet fonctionne-t-il, de façon répétée ? »
Pour les tests de bout en bout automatisés, mettez en place un domaine ou un sous-domaine que vous contrôlez, avec une boîte fourre-tout ou un webhook entrant, pour que votre code de test puisse lire le courrier via une API. Cela demande un certain effort de configuration, mais c'est privé et stable, et cela ne dépend du site de personne d'autre. N'inventez pas d'adresses sur des domaines que vous ne possédez pas. Quelqu'un possède peut-être testuser@gmail.com, et il recevra ce que vous envoyez. La RFC 2606 réserve example.com ainsi que les noms de premier niveau .test et .example pour que la documentation et les données de test aient un endroit sûr où pointer. Ces noms ne peuvent pas recevoir de courrier, ce qui les rend parfaits pour des jeux de données et inutiles pour des tests de livraison.
Une vraie boîte temporaire externe : « le domaine d'un inconnu recevrait-il ceci ? »
C'est là qu'une boîte temporaire gagne sa place. C'est une vraie boîte e-mail sur un domaine que vous ne contrôlez pas et pour lequel vous n'avez aucune liste d'autorisation. Votre message doit trouver l'enregistrement MX, établir une connexion SMTP et être accepté. Sur VookMail, les enregistrements MX des domaines pointent vers un fournisseur de distribution de courrier qui reçoit le message et le transmet en HTTPS. Une adresse neuve signifie aussi aucun historique : pas d'anciens messages, pas de rebond antérieur dans votre liste de suppression, pas de filtres. C'est donc un moyen rapide de reproduire « je me suis inscrit avec une nouvelle adresse et je n'ai rien reçu ». C'est aussi utile pour ceux qui ne sont pas développeurs. Un designer ou un responsable produit peut lire ce que reçoit un nouvel utilisateur sans aucun accès à vos outils.
Des comptes témoins chez les grands fournisseurs : « où cela atterrit-il ? »
Un message livré à un domaine ne dit rien du dossier spam d'un autre. Gardez un petit ensemble de vrais comptes chez les fournisseurs que vos utilisateurs emploient réellement, et vérifiez le placement avant les changements importants de modèle ou de domaine. Surveillez ensuite les chiffres de rebonds et de plaintes après une mise en production. Si votre courrier ressemble à un problème de spam, ces comptes sont l'endroit où vous le verrez en premier.
| Approche | Traverse internet | Mise en place | Automatisation | Confidentialité du contenu | Meilleure étape |
|---|---|---|---|---|---|
| Utilitaire de test du framework | Non | Aucune | Excellente | Reste dans le processus | Tests unitaires et fonctionnels |
| Collecteur SMTP local | Non | Faible | Bonne | Reste en local | Développement |
| Mode test du fournisseur | Généralement non | Faible | Bonne | Reste chez le fournisseur | Tests d'intégration |
| Votre propre domaine de test | Oui | Moyenne à élevée | Bonne | Vous le contrôlez | Bout en bout en CI, préproduction |
| Boîte temporaire | Oui | Aucune | Déconseillée | À considérer comme publique | QA manuelle et vérifications avant mise en production |
| Comptes témoins | Oui | Moyenne | Limitée | Modérée | Vérifications de placement |
Un passage manuel avec une boîte temporaire
Voici un parcours reproductible d'un flux d'inscription en préproduction ou dans un environnement de pré-production. Il devrait prendre environ dix minutes une fois que vous le connaissez.
- Confirmez que l'environnement utilise la même configuration de fournisseur que la production, hors identifiants, et ne contient que des données inventées. Si ce n'est pas le cas, notez-le, car cela limite ce que vous pouvez conclure.
- Ouvrez VookMail et appuyez sur Nouveau. Saisissez un nom d'utilisateur qui encode le test, comme
email-signup-03-x7, choisissez l'un des plus de 30 domaines, et appuyez sur la flèche. Utilisez le bouton jaune « Aléatoire » si quoi que ce soit dans le courrier pourrait être sensible, car quiconque connaît ou devine une adresse peut ouvrir cette boîte. - Appuyez sur Copier et inscrivez-vous comme nouvel utilisateur avec des données de profil inventées.
- Notez l'heure d'envoi du formulaire et l'heure d'apparition du message. La boîte vérifie toutes les quelques secondes : un écart de plusieurs minutes pointe donc vers votre file d'attente ou votre fournisseur. Appuyez sur Actualiser si vous voulez en être sûr.
- Lisez le message comme le ferait un nouvel utilisateur : nom de l'expéditeur, objet, texte d'aperçu, corps, bouton, lien brut, pied de page. VookMail affiche les codes et liens de confirmation détectés au-dessus du message, ce qui est un contrôle approximatif de la facilité à repérer votre code et votre lien.
- Regardez-le avec les images désactivées. VookMail garde les images désactivées jusqu'à ce que vous les autorisiez et retire les pixels espions cachés. Si le message n'a aucun sens dans cet état, certains de vos utilisateurs voient la même chose. N'utilisez toutefois pas cette boîte pour juger votre suivi des ouvertures, puisque les pixels ne se déclencheront pas.
- Appuyez sur le bouton QR, scannez l'adresse avec un téléphone de test et ouvrez-y la même boîte pour toucher le vrai lien sur un vrai appareil, surtout si vous utilisez des liens universels ou des app links.
- Terminez la vérification et confirmez que l'état du compte change comme prévu.
- Lancez les cas négatifs de la liste de contrôle ci-dessous : réutilisez le lien, laissez passer l'expiration, demandez un nouvel envoi.
- Conservez vos preuves : captures d'écran, horodatages et adresse utilisée. Les messages sont supprimés au bout d'environ une journée : un rapport de bug écrit la semaine prochaine n'aura donc rien à montrer.
- Appuyez sur Supprimer et retirez le compte de test si votre processus l'exige.
Plusieurs adresses peuvent être gardées dans un même navigateur : l'invitant et l'invité, ou l'ancienne et la nouvelle adresse d'un changement d'e-mail, peuvent donc être ouverts en même temps. Si vous joignez des fichiers dans votre test, souvenez-vous que VookMail refuse les fichiers de programme courants comme .exe et affiche un avertissement sur les archives : une pièce jointe rejetée là-bas n'est donc pas forcément un bug de votre côté.
Lire un échec
« L'e-mail n'est jamais arrivé » décrit un symptôme qui peut venir d'environ six endroits, et les équipes perdent des heures en commençant au mauvais. Avancez le long du chemin depuis votre code vers l'extérieur, et arrêtez-vous au premier endroit où vous ne voyez plus le message.
- L'application a-t-elle essayé ? Cherchez dans le journal de l'application la tentative d'envoi et toute exception. Cherchez une tâche qui n'a jamais été créée, souvent parce qu'une condition ou un feature flag était faux.
- Le worker a-t-il tourné ? Cherchez les tâches bloquées, en échec ou relancées. Un worker de file d'attente qui n'a pas été redémarré après un déploiement peut exécuter l'ancien code, et une politique de nouvelle tentative peut envoyer des doublons.
- Le fournisseur l'a-t-il accepté ? Cherchez le destinataire ou le
Message-IDdans le journal d'activité de votre fournisseur. Accepté, différé, rejeté et abandonné sont quatre histoires différentes. - A-t-il été supprimé ? Si cette adresse a déjà rebondi ou déposé une plainte, beaucoup de fournisseurs ignorent discrètement les envois suivants. Cela piège souvent les testeurs qui réutilisent une ancienne adresse.
- Qu'a dit le serveur récepteur ? Les journaux du fournisseur montrent généralement la réponse SMTP, et ce texte est la ligne la plus utile de toute l'enquête.
- Le DNS est-il correct ? Vérifiez SPF, DKIM et DMARC pour le domaine d'envoi réel.
- Est-il là mais caché ? Dossiers spam, onglets et filtres du client viennent en dernier, une fois qu'un compte témoin peut vous le montrer.
Ce que vous dit la réponse SMTP
Selon la RFC 5321, une réponse qui commence par 4 est un échec temporaire, et l'expéditeur doit réessayer plus tard. Une réponse qui commence par 5 est permanente. Les codes d'état améliorés de la RFC 3463 ajoutent du détail ensuite. Une ligne de journal inventée pourrait ressembler à ceci, uniquement comme exemple de format :
Exemple uniquement : to=user@gmail.example status=bounced reply="550 5.7.26 unauthenticated sender"
Lisez de gauche à droite. Le 5 signifie que les nouvelles tentatives n'aideront pas. La famille 5.7 concerne la sécurité ou la politique, ce qui vous envoie vers le DNS et la signature, et vous éloigne de l'adresse du destinataire. Le tableau ci-dessous donne un point de départ pour les cas courants.
| Ce que vous voyez | Couche la plus probable | Premier endroit où regarder |
|---|---|---|
| Rien dans le journal du fournisseur | Application ou file d'attente | Journaux de l'application et tâches en échec |
| Le fournisseur dit « dropped » ou « suppressed » | Liste de suppression du fournisseur | Retirez l'adresse de test, ou utilisez-en une nouvelle |
| L'API renvoie un succès, mais rien n'est jamais journalisé comme envoyé | Mode bac à sable encore actif | Réglages du fournisseur pour cet environnement |
5.1.1 ou similaire | Adresse du destinataire | Fautes de frappe, et validation du formulaire qui a modifié l'adresse |
5.7.26 chez Gmail | Authentification | SPF, DKIM et alignement avec le domaine From |
Différés 4xx qui se résorbent après un moment | Le récepteur vous ralentit | Volume, réputation, ou nouvelle IP d'envoi |
| Livré dans une boîte externe, absent chez Gmail | Politique ou filtrage du récepteur | Comptes témoins et consignes de Google pour les expéditeurs |
| Arrive, mais le lien dit « déjà utilisé » | Un analyseur précharge le lien | Consommez les jetons en POST, pas en GET |
| Le lien mène à un avertissement de sécurité | Domaine de suivi des clics | Certificat du sous-domaine de suivi |
| Arrive en double | Logique de nouvelle tentative | Idempotence des tâches et délais d'expiration qui déclenchent les nouvelles tentatives |
| Arrive très tard | File d'attente | Capacité des workers, et si le courrier de réinitialisation partage une file avec le courrier en masse |
Cette dernière ligne est un point de conception qui mérite une phrase de plus. Si les réinitialisations de mot de passe partagent une file avec l'envoi d'une newsletter, elles attendent derrière. Donnez au courrier transactionnel sa propre file, et idéalement son propre sous-domaine et son propre flux d'envoi, pour qu'un problème de marketing ne retarde pas une connexion.
Des commandes qui raccourcissent la recherche
Vous pouvez vérifier l'essentiel sans quitter votre terminal. Dans ces exemples, remplacez les noms d'exemple par les vôtres.
dig +short MX example.commontre où un domaine reçoit son courrier. Une réponse vide demande un examen plus attentif, car la RFC 5321 permet aux expéditeurs de se rabattre sur un enregistrement d'adresse, tandis qu'une réponse0 .est un MX nul au sens de la RFC 7505, c'est-à-dire que le domaine n'accepte aucun courrier.dig +short TXT example.commontre l'enregistrement SPF parmi d'autres enregistrements texte.dig +short TXT selector._domainkey.example.commontre une clé DKIM. Prenez le vrai sélecteur dans la valeurs=de l'en-têteDKIM-Signaturedu message.dig +short TXT _dmarc.example.commontre la politique DMARC.openssl s_client -starttls smtp -connect smtp.example.com:587vérifie que vous pouvez joindre votre relais et montre son certificat. Un échec ici signifie un problème de pare-feu ou de TLS, bien avant quoi que ce soit sur le contenu.swaks --to qa@example.test --from app@example.test --server localhost:1025envoie un message simple à la main. Il contourne votre application, ce qui permet de savoir si un problème vient de votre code ou de la route.
Pour des preuves au niveau des en-têtes, la vue la plus fiable est une boîte e-mail que vous contrôlez chez un grand fournisseur. Dans Gmail, ouvrez le message, utilisez le menu à trois points et choisissez Afficher l'original, qui liste en haut les résultats SPF, DKIM et DMARC. Gardez à l'esprit qu'un « pass » chez un récepteur ne garantit pas celui d'un autre.
Que vérifier dans chaque flux
« Est-ce arrivé ? » est la première question, et généralement la moins intéressante. Chaque flux a ensuite ses propres façons de mal tourner.
Réinitialisation de mot de passe
Le OWASP Forgot Password Cheat Sheet est la référence sur laquelle s'appuyer ici. Il demande un message identique que le compte existe ou non, des réponses qui prennent un temps uniforme, des jetons aléatoires, longs, stockés de façon sécurisée et à usage unique, et Referrer-Policy: no-referrer sur la page de réinitialisation.
- La page de demande affiche le même message pour les adresses enregistrées et non enregistrées, et prend à peu près le même temps. Une réponse instantanée pour les adresses inconnues fuit autant que la formulation le ferait.
- Le lien fonctionne une fois. Ouvrez-le une seconde fois et vous obtenez une explication claire avec un moyen d'en demander un autre.
- Demander une nouvelle réinitialisation invalide les anciens liens, ou votre conception en décide autrement exprès.
- L'expiration est appliquée par le serveur et a été testée en attendant, ou en changeant l'heure dans un environnement de test.
- Une réinitialisation réussie envoie un e-mail de confirmation, et les autres sessions sont traitées selon votre politique.
- Ouvrir le lien ne modifie rien en soi. Le jeton est consommé à l'envoi du formulaire.
- La page de réinitialisation n'envoie pas son URL à des outils d'analyse ou de suivi d'erreurs tiers.
- Les limites de débit s'appliquent par compte aussi bien que par IP, pour que personne ne puisse inonder la boîte d'un inconnu.
- Les adresses avec majuscules et minuscules ou avec un signe plus fonctionnent comme les adresses simples.
Vérification d'inscription
- Une inscription envoie un message, y compris quand la tâche est relancée.
- Le lien ou le code fonctionne une fois, et la page du lien expiré propose une suite.
- Un nouvel envoi invalide soit le jeton précédent, soit coexiste avec lui comme prévu, et est limité en débit.
- Les comptes non vérifiés ont exactement les restrictions voulues.
- Se réinscrire avec une adresse enregistrée n'indique pas à un visiteur anonyme que le compte existe, si votre produit juge cela sensible. Un schéma courant consiste à envoyer plutôt un e-mail au propriétaire existant.
- Le lien pointe vers le bon environnement. Un message de préproduction qui renvoie vers la production finira tôt ou tard par modifier des données de production.
Codes de connexion et liens magiques
- Les codes sont assez longs, expirent vite et ont une limite de tentatives.
- Les liens magiques affichent une page d'arrivée avec un bouton, et sont consommés sur ce POST, de sorte que le GET d'un analyseur ne cause aucun dégât.
- Ouvrir le lien sur un autre appareil fait ce que dit votre conception, et l'utilisateur comprend ce qui s'est passé.
- L'objet ne contient un code que si vous avez décidé que c'est acceptable, puisque les notifications l'affichent sur l'écran verrouillé.
Changement d'adresse e-mail
- La confirmation va à la nouvelle adresse, et rien ne change tant qu'elle n'est pas confirmée.
- Un avis va à l'ancienne adresse, pour que le vrai propriétaire puisse réagir à un changement non autorisé.
- Les jetons de réinitialisation en cours cessent de fonctionner après le changement.
- Deux boîtes temporaires rendent celui-ci rapide à exécuter à la main.
Invitations, reçus et notifications
- Une invitation envoyée à une personne sans compte mène à l'inscription avec l'adresse préremplie ou verrouillée, comme prévu. Une invitation expirée ou révoquée l'indique.
- Une invitation ne peut pas être acceptée par un autre compte, sauf si votre conception l'autorise.
- Les reçus affichent les bons montants, devises, dates et fuseaux horaires pour les paramètres régionaux de l'utilisateur, et les pièces jointes ont des noms sensés et s'ouvrent correctement.
- Les changements de préférences prennent effet à l'envoi suivant.
- Le courrier non essentiel a un désabonnement fonctionnel, et le courrier de compte et de sécurité est clairement séparé. Notre article sur la surcharge de newsletters montre à quoi cela ressemble du côté du lecteur.
- Des modèles traduits existent pour chaque langue prise en charge, avec une mise en page de droite à gauche correcte le cas échéant, et sans fragment non traduit dans l'objet.
Relire le code des jetons
Tester via une boîte de réception montre un comportement. Une brève revue de code attrape des défauts de conception qu'aucune boîte ne vous montrera. Quand vous lisez le code derrière la réinitialisation, la vérification et les liens magiques, cherchez ceci.
- La source d'aléa. Ce doit être un générateur cryptographiquement sûr, comme
secrets.token_urlsafe(32)en Python,crypto.randomBytes(32)en Node ourandom_bytes(32)en PHP. Un horodatage, un identifiant incrémental ou un hachage de l'e-mail n'est pas acceptable. - La longueur. Les jetons de lien portent couramment au moins 128 bits d'aléa. Un code à six chiffres n'est acceptable qu'avec une expiration serrée et une limite de tentatives.
- Le stockage. Conservez un hachage du jeton, pour qu'une fuite de la base de données ne distribue pas de liens de réinitialisation fonctionnels.
- La comparaison. Utilisez une fonction à temps constant comme
hmac.compare_digest,hash_equalsoucrypto.timingSafeEqualquand vous comparez directement des valeurs secrètes. - La finalité. Un jeton de vérification ne doit pas fonctionner comme jeton de réinitialisation, et un jeton pour un compte ne doit pas fonctionner pour un autre.
- L'expiration. Le serveur conserve l'heure d'expiration, qui ne peut donc pas être modifiée en éditant le lien.
- L'invalidation. L'utilisation du jeton, un changement de mot de passe par une autre voie ou un changement d'e-mail doivent tous annuler les jetons en cours.
- La journalisation. Les URL complètes avec jetons ne doivent pas atteindre les journaux de l'application, les événements d'analyse ni les outils de suivi d'erreurs. Vérifiez aussi vos journaux d'accès HTTP.
En-têtes et authentification
Ouvrez la source brute dans un collecteur pour voir ce qu'a produit votre application, et dans une boîte que vous contrôlez chez un grand fournisseur pour voir ce que le fournisseur et le réseau ont ajouté.
| En-tête ou élément | Ce qu'il faut vérifier |
|---|---|
From | Le bon nom de marque, sur un domaine que vous possédez et authentifiez |
Reply-To | Une boîte e-mail surveillée, ou omis exprès |
Return-Path | Le domaine de rebond, aligné avec votre domaine si vous comptez sur SPF pour DMARC |
DKIM-Signature | Présent, avec un domaine d= aligné avec le domaine From |
Message-ID | Présent et unique, car c'est votre clé de traçage dans les journaux du fournisseur |
Content-Type | multipart/alternative avec des parties HTML et texte brut |
List-Unsubscribe, List-Unsubscribe-Post | Présents sur le courrier en masse et marketing, avec prise en charge du désabonnement en un clic selon la RFC 8058 |
Auto-Submitted | auto-generated sur le courrier automatisé, comme défini dans la RFC 3834, pour aider à éviter les boucles de réponse |
Quelques règles à vérifier avant de mettre en production un nouveau domaine d'envoi. Une évaluation SPF ne doit pas dépasser dix requêtes DNS (RFC 7208), et dépasser la limite est un moyen facile d'échouer après avoir ajouté un fournisseur de plus à votre enregistrement. DKIM exige que l'enregistrement du sélecteur du fournisseur soit publié et vérifie. DMARC exige un enregistrement sur votre domaine From, commençant généralement à p=none avec les rapports activés, puis resserré une fois l'alignement confirmé.
Le volume change aussi les règles. Les consignes de Google considèrent un expéditeur comme expéditeur en masse à environ 5 000 messages par jour vers des comptes Gmail personnels, et les expéditeurs en masse ont besoin de SPF, DKIM et DMARC, du désabonnement en un clic sur le courrier promotionnel, et d'un taux de spam signalé par les utilisateurs gardé sous 0,3 %, avec 0,1 % comme objectif recommandé. D'autres fournisseurs ont leurs propres règles. Amazon SES, par exemple, place un compte sous examen à un taux de rebond de 5 % ou un taux de plainte de 0,1 %. Lisez les chiffres actuels dans la documentation de votre fournisseur avant de planifier autour d'eux, car ils changent.
Gestion et validation des adresses
Les formulaires rejettent des adresses valides plus souvent qu'on ne le pense, et un bug de validation en amont peut ressembler exactement à un échec de livraison. Testez le vôtre avec ceci.
| Saisie | Traitement attendu | Bug courant |
|---|---|---|
user+tag@example.com | Accepter | Une expression régulière rejette le signe plus |
User@Example.COM | Accepter, et traiter le domaine sans tenir compte de la casse | Comptes en double qui ne diffèrent que par la casse |
o'brien@example.com | Accepter | Rejetée, ou casse une requête ou un modèle si elle n'est pas échappée |
first.last@sub.example.co.uk | Accepter | La validation suppose un seul point dans le domaine |
| Espaces au début ou à la fin | Supprimer d'abord | « E-mail invalide » sur un collage correct |
| Une adresse très longue | Imposer 64 caractères pour la partie locale et 254 au total | Une colonne de base de données trop courte la tronque en silence |
| Domaines et adresses internationalisés | Accepter ou refuser de façon cohérente, avec un message clair | Un plantage dans l'encodage ou la journalisation |
| Un domaine sans route de courrier | Avertir ou rejeter | Un compte qui ne pourra jamais être vérifié |
Validez de façon souple dans le formulaire, puis laissez l'e-mail de confirmation prouver que l'adresse fonctionne. Une expression régulière stricte vous fait perdre de vrais utilisateurs et vous dit très peu sur l'existence d'une boîte e-mail.
Si votre produit refuse les domaines jetables en production, votre processus QA a quand même besoin d'un passage en préproduction. Les options comprennent une liste d'autorisation de domaines de test hors production, un indicateur qui désactive le contrôle dans les environnements de test, ou votre propre domaine de test. N'affaiblissez pas la règle de production pour faciliter les tests. Et si vous hésitez à avoir cette règle, notre article sur les raisons pour lesquelles des sites bloquent les e-mails jetables expose les coûts et les avantages du point de vue d'un propriétaire.
Comment cela s'affiche
L'affichage est l'endroit où la revue d'un designer aide le plus, et elle demande de vrais messages dans de vrais clients.
- La partie texte brut se lit bien et inclut le lien complet. « Cliquez sur le bouton ci-dessous » n'y sert à rien.
- Le mode sombre laisse les logos visibles et garde le contraste. VookMail a un mode sombre, ce qui est un début, et les clients que vos utilisateurs préfèrent sont le vrai test.
- Avec les images bloquées, l'appel à l'action reste un vrai lien texte ou un bouton HTML.
- Les boutons sont assez grands pour être touchés, et les longues URL ne cassent pas la mise en page sur téléphone.
- Le texte d'aperçu est écrit exprès, sans reste de formulation du modèle.
- Les titres sont sémantiques, le contraste est suffisant, le texte des liens est descriptif et le HTML a un attribut de langue.
- Les données manquantes ne produisent pas « Bonjour {first_name} » ou « Bonjour , ».
- La taille du message reste bien en dessous d'environ 102 Ko, le seuil à partir duquel Gmail tronquerait les longs messages selon de nombreux témoignages. La troncature peut cacher votre pied de page et tout lien de désabonnement qui s'y trouve.
Garde-fous contre les accidents
Les incidents d'e-mail embarrassants sont surtout des erreurs de configuration : du courrier de préproduction qui atteint de vrais clients, la production sur une clé de test, des liens vers localhost. Quelques réglages en évitent la plupart.
Gardez des identifiants séparés par environnement, dans des variables d'environnement ou un gestionnaire de secrets. Hors production, utilisez une liste d'autorisation de destinataires pour que l'outil d'envoi ne livre qu'aux domaines de test approuvés et redirige ou abandonne tout le reste. Construisez chaque lien à partir d'un seul réglage, comme APP_URL, pour que les modèles ne contiennent aucun hôte écrit en dur. Préfixez les objets hors production avec quelque chose comme [STAGING] pour qu'un message mal dirigé soit évident pour son destinataire.
Si vous copiez des données de production en préproduction, remplacez chaque vraie adresse par une adresse synthétique avant qu'aucun worker de courrier ne démarre. L'ordre compte, car un worker qui démarre en premier peut se mettre tout de suite à traiter du courrier programmé. Et suivez délibérément le mode bac à sable de chaque environnement. Lancer avec la production encore en bac à sable est un classique : l'API renvoie un succès, les journaux ont l'air propres, et aucun courrier ne part.
Les suites automatisées doivent rester sur une infrastructure que vous contrôlez
Une boîte temporaire publique est la mauvaise dépendance pour la CI. Extraire le contenu de la page web de quelqu'un d'autre est fragile, et vos builds échoueraient pour des raisons sans rapport avec votre code. Cela place aussi votre trafic de test sur un service que vous n'exploitez pas. Les messages y sont lisibles par quiconque a l'adresse : rien d'automatisé ne devrait donc en dépendre.
Une organisation sensée ressemble à ceci. Les utilitaires du framework vérifient que le bon courrier est demandé. Un conteneur Mailpit dans votre pile de test reçoit le vrai message, et votre test le lit via l'API HTTP de Mailpit (GET /api/v1/messages), en extrait le lien et le suit. Le mode test du fournisseur exerce les webhooks et la gestion des erreurs. Une tâche nocturne sur votre propre domaine de test envoie via le vrai fournisseur et lit le résultat via un webhook entrant, ce qui vous donne chaque jour un signal que la vraie livraison fonctionne encore.
Le courrier temporaire a sa place dans les parties humaines du test : séances exploratoires où vous avez vite besoin d'une identité neuve, test de fumée avant la mise en production, reproduction du signalement d'un utilisateur, revues de texte et de design, et tests sur téléphone. Pour ce dernier cas, le bouton QR ou l'application de Google Play ou de Huawei AppGallery amène la boîte sur un appareil de test. Vérifiez que les liens ouvrent votre application quand elle est installée et se rabattent sur une page web fonctionnelle quand elle ne l'est pas, et que l'application remarque l'état vérifié sans exiger une nouvelle connexion.
Un cas de test qui survit à une passation
Des cas de test cohérents sont plus faciles à répéter à chaque version et à transmettre entre testeurs. Cet exemple comporte les champs qui ont tendance à compter.
| Champ | Exemple |
|---|---|
| ID du test | EMAIL-RESET-03 |
| Flux | Réinitialisation de mot de passe, réutilisation du jeton |
| Préconditions | Compte de test vérifié en préproduction, avec une adresse temporaire neuve |
| Étapes | Demander une réinitialisation, ouvrir le lien, définir un nouveau mot de passe, rouvrir le même lien |
| Résultat attendu | La seconde utilisation explique que le lien n'est plus valide et propose une nouvelle demande |
| Preuves | Captures d'écran, Message-ID si disponible, horodatages, adresse utilisée |
| Environnement | Numéro de build de la préproduction et configuration du courrier |
Mettre l'ID du test dans le nom d'utilisateur, comme dans email-reset-03-x7, relie chaque boîte à son cas et évite que deux testeurs se heurtent sur une même adresse. Le court suffixe aléatoire est là parce que n'importe qui peut ouvrir une boîte s'il en devine le nom.
Ce qu'il ne faut pas envoyer à une boîte publique
Considérez toute boîte temporaire comme lisible par quiconque connaît l'adresse, et testez en conséquence.
- N'envoyez que des données synthétiques : faux noms, fausses commandes, fausses adresses. Les données de vrais clients n'ont rien à y faire, et selon l'endroit où vous exercez, les envoyer pourrait aussi vous causer un problème juridique.
- N'envoyez jamais de clés d'API, d'identifiants de base de données ni d'invitations d'administrateur pour de vrais systèmes.
- Supprimez régulièrement les comptes de test, surtout ceux qui ont des privilèges. Un utilisateur de test administrateur lié à une boîte publique est une porte d'entrée si quelqu'un d'autre ouvre cette boîte et demande une réinitialisation. Puisque l'adresse ne vous est pas réservée une fois vidée, ce risque persiste après le test.
- N'utilisez jamais une adresse temporaire comme propriétaire d'un vrai compte de production ou d'un service tiers dont votre entreprise dépend.
- Connaissez la durée de conservation. Les messages et les pièces jointes disparaissent au bout d'environ une journée, et la politique de confidentialité donne les détails.
Tester votre propre produit est l'un des usages légitimes les plus nets de l'e-mail jetable. Gardez-le ainsi : testez des systèmes que vous possédez ou que vous êtes autorisé à tester. N'utilisez pas de boîtes temporaires pour créer des comptes sur les services d'autres entreprises contre leurs conditions, pour collectionner des périodes d'essai, ni pour tester la charge du formulaire d'inscription de quelqu'un d'autre. Les conditions générales couvrent l'usage acceptable, et la page de méthodologie explique comment le service fonctionne. VookMail fait partie du réseau d'outils gratuits PAYATE.
Avant la mise en production
- SPF, DKIM et DMARC vérifiés pour le domaine d'envoi réel de production, avec le domaine
Fromaligné. - Outil d'envoi de production avec les identifiants de production, mode bac à sable désactivé, confirmé par un vrai message.
- Vérification d'inscription reçue à une adresse externe neuve, lien utilisé une fois, expiration testée.
- Réinitialisation de mot de passe testée de bout en bout, y compris des réponses identiques pour les adresses inconnues et le message de confirmation.
- Jetons de réinitialisation et de lien magique consommés à l'envoi d'un formulaire, pour que le GET d'un analyseur ne les épuise pas.
- Le changement d'e-mail écrit à la fois à la nouvelle et à l'ancienne adresse.
- Tous les liens pointent vers l'hôte de production en HTTPS, y compris ceux réécrits par le suivi des clics.
- Courrier transactionnel séparé du courrier en masse, au moins dans sa file d'attente.
- HTML et texte brut présents et lisibles, mode sombre et images bloquées vérifiés.
- Une vérification de placement sur des comptes témoins si le domaine ou le modèle a changé de façon notable.
- Désabonnement fonctionnel sur le courrier non essentiel, et modèles traduits relus.
- Preuves jointes au ticket de mise en production, et chiffres de rebonds et de plaintes sur un tableau de bord que quelqu'un surveillera après le lancement.
Questions que les développeurs posent à ce sujet
Une vraie boîte a accepté mon courrier. Suis-je tranquille chez Gmail ?
Non. La livraison à un domaine montre que votre message est parti, a trouvé une route et a été accepté là-bas. Gmail applique ses propres règles d'authentification et de filtrage, comme tous les autres grands fournisseurs. Utilisez des comptes témoins et les Postmaster Tools de Google pour cette question.
Puis-je réutiliser la même adresse de test ?
Vous le pouvez au sein d'une session, mais une adresse neuve donne un test plus propre. Les anciennes adresses accumulent des entrées de suppression et d'anciens messages, et sur un service temporaire la boîte est de toute façon vidée au bout d'environ une journée.
Le courrier arrive dans mon collecteur mais pas à l'extérieur. Par où commencer ?
Un collecteur montre que votre application a produit un message et rien d'autre : commencez donc par le journal d'activité du fournisseur. Le plus souvent, la réponse est un réglage de bac à sable, une entrée de suppression, de mauvais identifiants, ou un rejet SMTP qui nomme l'authentification.
Combien de temps un lien de réinitialisation doit-il rester valide ?
Assez court pour limiter les dégâts et assez long pour que le courrier lent arrive. Beaucoup d'équipes se fixent entre 15 minutes et une heure, mais cela dépend de votre risque et de la rapidité de livraison de votre courrier, et le courrier de vos utilisateurs peut être retardé hors de votre contrôle. Quel que soit votre choix, testez l'état expiré et dites aux gens quoi faire ensuite.
