Angenommen, dein Team liefert eine neue Mail zum Zurücksetzen des Passworts aus. Die QA gibt Staging frei: Die Nachricht erscheint, der Link funktioniert, die Vorlage sieht richtig aus. Zwei Tage nach dem Release hat der Support eine Warteschlange voller Tickets. Leute mit Gmail-Adressen sagen, die Mail sei nie angekommen. Leute bei ein paar großen Firmen sagen, sie sei angekommen, aber der Link sei beim ersten Klick „bereits verwendet“ gewesen. Zwischen Staging und Produktion hat niemand den Code geändert, und jeder Test besteht weiterhin.
Welche Test-E-Mail-Adresse für Entwickler hätte das aufgedeckt? Keine einzelne. Ein lokaler SMTP-Catcher eignet sich für die tägliche Entwicklung, die Sandbox deines Anbieters oder eine Testdomain, die du kontrollierst, für automatisierte Tests, und ein echtes externes Postfach für die manuelle Prüfung, dass Mail dein produktionsnahes Setup verlässt und die Domain eines Fremden erreicht. Ein temporäres Postfach wie VookMail deckt diesen letzten Fall ohne Einrichtung ab, weil beim Laden der Seite eine Adresse bereitsteht. Seed-Konten bei großen Postfachanbietern decken dann den Teil ab, den keine dieser Möglichkeiten sehen kann. Der Rest dieses Leitfadens handelt davon, aus diesen Optionen zu wählen, Fehler zu lesen, wenn sie auftreten, und den Prüfungen, die in ein Release gehören.
Warum der Reset auf Staging bestand
Staging und Produktion sind selten so ähnlich, wie das Deployment-Diagramm vermuten lässt, und E-Mail bringt die Unterschiede stärker ans Licht als die meisten Funktionen. Eine Nachricht läuft durch deine Anwendung, eine Warteschlange, einen Anbieter, DNS, den Server des Empfängers und dessen Client. Staging nutzt vielleicht bei fast allen davon eine andere Version.
Nimm das erste Ticket, die Gmail-Nutzer, die nichts bekamen. Angenommen, Staging sendet über eine Subdomain des Anbieters, die vor Monaten authentifiziert wurde, während die Produktion von einer neuen From-Domain sendet, die mit dem Rebranding eingeführt wurde. Googles Richtlinien für Absender verlangen von allen Absendern eine Authentifizierung mit SPF oder DKIM, und die Gmail-Fehlertabelle nennt 5.7.26 für nicht authentifizierte Mail. Ein internes QA-Postfach auf deiner eigenen Domain winkt dieselbe Nachricht vielleicht durch, weil dein eigener Server deinem eigenen Relay vertraut. Der Test hätte nie scheitern können.
Das zweite Ticket, der Link „bereits verwendet“, hat eine andere Ursache. Sicherheits-Gateways in Unternehmen öffnen häufig Links in eingehender Post, um sie zu prüfen, bevor die Person sie sieht. Löst dein Link das Token bei einer einfachen GET-Anfrage ein, verbraucht der Scanner es, und der Mitarbeiter klickt auf einen toten Link. Kein Staging-Postfach von dir betreibt diesen Scanner, außer deine eigene Firma setzt zufällig einen ein.
Diese beiden Fehler lassen sich nicht vom selben Ort aus sehen. Der eine braucht echte Zustellung an ein empfangendes System, das du nicht betreibst. Der andere braucht eine Änderung daran, wie sich der Link verhält, was ein Review leichter findet als ein Test. Das ist das Argument für geschichtetes Testen: Jede Art von Adresse beantwortet eine Frage und schweigt zu den anderen.
| Unterscheidet sich oft zwischen Staging und Produktion | Was es verbergen kann |
|---|---|
Sende-Domain und From-Adresse | Fehlendes oder nicht ausgerichtetes SPF und DKIM |
| Konto oder Unterkonto beim Anbieter | Sandbox-Modus, Sendelimits, ein anderer IP-Ruf |
| Empfänger | Interne Domains, die dir vertrauen, und Allowlists, die schlechte Adressen verbergen |
| Klick-Tracking | Umgeschriebene Links, die kaputtgehen, oder eine Tracking-Domain ohne gültiges Zertifikat |
| Menge | Warteschlangen und Ratenlimits, die erst unter Last greifen |
| Unterdrückungslisten | Produktivadressen, die einmal zurückgewiesen wurden und nun stillschweigend übersprungen werden |
| Einstellungen der Basis-URL | Links, die auf den falschen Host zeigen |
Welche Adresse welche Frage beantwortet
Hier sind die Optionen, jeweils mit der Frage, die sie wirklich beantworten kann.
Ein lokaler Catcher: „Was hat meine App erzeugt?“
Ein SMTP-Catcher nimmt alles an, was deine App sendet, und zeigt es auf einer Webseite an, ohne etwas zuzustellen. Mailpit ist eine beliebte Open-Source-Wahl. Standardmäßig lauscht es für SMTP auf Port 1025 und bietet seine Weboberfläche auf Port 8025 an, du richtest also deine Entwicklungseinstellungen auf localhost:1025 und öffnest http://localhost:8025. Nodemailers Ethereal ist eine ähnliche Idee mit einem gehosteten Fake-SMTP-Dienst. Ein Catcher ist schnell und privat, und er lässt dich an beliebige Adressen senden, ohne die Gefahr, einen echten Menschen zu erreichen. Über DNS, Authentifizierung oder Filterung sagt er nichts, weil nichts das Internet durchquert.
Der Test-Helfer eines Frameworks: „Hat mein Code die richtige Mail angefordert?“
Die meisten Frameworks können ausgehende Mail während eines Testlaufs im Speicher aufzeichnen. Laravel hat Mail::fake(), Django sammelt Nachrichten in django.core.mail.outbox, und Rails hat ActionMailer::Base.deliveries. Nutze sie, um zu prüfen, dass ein Job einmal mit dem richtigen Empfänger und Token ausgelöst wird. Sie liefern die schnellste Rückmeldung, die du bekommen kannst, und testen noch weniger von der Außenwelt als ein Catcher.
Der Testmodus eines Anbieters: „Funktioniert meine Integration?“
Anbieter helfen hier auf verschiedene Weise, und die Unterschiede zählen. Amazon SES hat einen Postfach-Simulator mit Adressen wie success@simulator.amazonses.com, bounce@simulator.amazonses.com und complaint@simulator.amazonses.com, die diese Ergebnisse erzeugen, ohne deinem Ruf zu schaden. Ein neues SES-Konto startet außerdem in einer Sandbox, in der es nur an verifizierte Adressen senden kann. Der Sandbox-Modus von SendGrid, gesetzt über mail_settings.sandbox_mode.enable, validiert deine Anfrage, ohne zuzustellen. Postmark akzeptiert für denselben Zweck das Token POSTMARK_API_TEST. Sie eignen sich für API-Fehler und für Webhooks bei Bounces und Beschwerden, und sie zeigen nicht, dass Mail bei jemandem ankam. Prüfe die aktuelle Dokumentation deines Anbieters, denn diese Funktionen ändern sich.
Eine Testdomain, die dir gehört: „Funktioniert der ganze Ablauf, wiederholt?“
Richte für automatisierte End-to-End-Tests eine Domain oder Subdomain ein, die du kontrollierst, mit einem Catch-all-Postfach oder einem eingehenden Webhook, damit dein Testcode die Mail über eine API lesen kann. Das braucht etwas Aufwand beim Einrichten, ist aber privat und stabil und hängt von niemandes Website ab. Erfinde keine Adressen bei Domains, die dir nicht gehören. Jemandem gehört vielleicht testuser@gmail.com, und er bekommt, was du schickst. RFC 2606 reserviert example.com sowie die Top-Level-Namen .test und .example, damit Dokumentation und Testdaten einen sicheren Verweis haben. Diese Namen können keine Mail empfangen, was sie für Fixtures richtig und für Zustelltests nutzlos macht.
Ein echtes externes temporäres Postfach: „Würde die Domain eines Fremden das empfangen?“
Hier verdient sich ein temporäres Postfach seinen Platz. Es ist ein echtes Postfach bei einer Domain, die du nicht kontrollierst und für die du keine Allowlist hast. Deine Nachricht muss den MX-Eintrag finden, eine SMTP-Verbindung aufbauen und angenommen werden. Bei VookMail zeigen die MX-Einträge der Domains auf einen Anbieter für Mailzustellung, der die Nachricht empfängt und per HTTPS weiterleitet. Eine frische Adresse bedeutet außerdem keine Vorgeschichte: keine alten Nachrichten, kein früherer Bounce auf deiner Unterdrückungsliste, keine Filter. Damit lässt sich schnell „Ich habe mich mit einer neuen Adresse registriert und nichts bekommen“ nachstellen. Es ist auch für Nicht-Entwickler nützlich. Ein Designer oder Produktmanager kann lesen, was ein neuer Nutzer bekommt, ohne Zugriff auf deine Werkzeuge.
Seed-Konten bei großen Postfachanbietern: „Wo landet es?“
Eine zugestellte Nachricht bei einer Domain sagt nichts über den Spam-Ordner bei einer anderen. Halte eine kleine Zahl echter Konten bei den Anbietern bereit, die deine Nutzer tatsächlich verwenden, und prüfe die Platzierung vor größeren Änderungen an Vorlage oder Domain. Beobachte dann nach einem Release die Zahlen zu Bounces und Beschwerden. Wenn deine Mail wie ein Spam-Problem aussieht, siehst du es an diesen Konten zuerst.
| Ansatz | Durchquert das Internet | Einrichtung | Automatisierung | Vertraulichkeit des Inhalts | Beste Phase |
|---|---|---|---|---|---|
| Test-Helfer des Frameworks | Nein | Keine | Hervorragend | Bleibt im Prozess | Unit- und Feature-Tests |
| Lokaler SMTP-Catcher | Nein | Gering | Gut | Bleibt lokal | Entwicklung |
| Testmodus des Anbieters | Meist nicht | Gering | Gut | Bleibt beim Anbieter | Integrationstests |
| Deine eigene Testdomain | Ja | Mittel bis hoch | Gut | Du kontrollierst sie | CI-End-to-End, Staging |
| Temporäres Postfach | Ja | Keine | Nicht empfohlen | Als öffentlich behandeln | Manuelle QA und Prüfungen vor dem Release |
| Seed-Konten | Ja | Mittel | Begrenzt | Mäßig | Prüfung der Platzierung |
Ein manueller Durchlauf mit einem temporären Postfach
Hier ist ein wiederholbarer Durchgang durch einen Registrierungsablauf auf Staging oder einer Vorproduktionsumgebung. Er sollte etwa zehn Minuten dauern, sobald du ihn kennst.
- Bestätige, dass die Umgebung abgesehen von den Zugangsdaten dieselbe Anbieterkonfiguration wie die Produktion nutzt und nur ausgedachte Daten enthält. Wenn nicht, schreibe das auf, denn es begrenzt, was du schlussfolgern kannst.
- Öffne VookMail und drücke auf Neu. Tippe einen Benutzernamen, der den Test kodiert, etwa
email-signup-03-x7, wähle eine der mehr als 30 Domains und drücke auf den Pfeil. Nimm den gelben Zufall-Button, wenn etwas in der Mail sensibel sein könnte, denn jeder, der eine Adresse kennt oder errät, kann dieses Postfach öffnen. - Drücke auf Kopieren und registriere dich als neuer Nutzer mit erfundenen Profildaten.
- Notiere die Zeit, zu der du abgeschickt hast, und die Zeit, zu der die Nachricht erscheint. Das Postfach prüft alle paar Sekunden, ein Abstand von Minuten deutet also auf deine Warteschlange oder deinen Anbieter. Drücke auf Aktualisieren, wenn du sichergehen willst.
- Lies die Nachricht, wie es ein neuer Nutzer täte: Absendername, Betreff, Vorschautext, Text, Button, einfacher Link, Fußbereich. VookMail zeigt erkannte Codes und Bestätigungslinks über der Nachricht an, was ein grober Test dafür ist, dass sich dein Code und dein Link leicht erkennen lassen.
- Sieh sie dir mit ausgeschalteten Bildern an. VookMail hält Bilder aus, bis du sie erlaubst, und entfernt versteckte Tracking-Pixel. Wenn die Nachricht in diesem Zustand keinen Sinn ergibt, sehen manche deiner Nutzer genau das. Beurteile mit diesem Postfach aber nicht dein Öffnungs-Tracking, denn Pixel lösen nicht aus.
- Drücke auf den QR-Button, scanne die Adresse mit einem Testhandy und öffne dort dasselbe Postfach, um auf einem echten Gerät den echten Link anzutippen, besonders wenn du Universal Links oder App Links nutzt.
- Schließe die Verifizierung ab und bestätige, dass sich der Kontostatus wie vorgesehen ändert.
- Führe die negativen Fälle aus der Checkliste unten aus: den Link erneut verwenden, den Ablauf abwarten, ein erneutes Senden anfordern.
- Sichere deine Belege: Screenshots, Zeitstempel und die verwendete Adresse. Nachrichten werden nach etwa einem Tag entfernt, ein Fehlerbericht, der nächste Woche geschrieben wird, hat also nichts mehr, worauf er zeigen kann.
- Drücke auf Löschen und entferne das Testkonto, wenn dein Prozess es verlangt.
Mehrere Adressen lassen sich in einem Browser halten, sodass ein Einladender und ein Eingeladener oder die alte und neue Adresse einer E-Mail-Änderung gleichzeitig offen sein können. Wenn du in deinem Test Dateien anhängst, denk daran, dass VookMail gängige Programmdateien wie .exe ablehnt und bei Archiven einen Warnhinweis zeigt, ein dort abgelehnter Anhang muss also kein Fehler auf deiner Seite sein.
Einen Fehler lesen
„Die E-Mail kam nie an“ beschreibt ein Symptom, das an etwa sechs Stellen liegen kann, und Teams verlieren Stunden, weil sie an der falschen anfangen. Gehe den Weg von deinem Code nach außen und halte an der ersten Stelle an, an der du die Nachricht nicht mehr sehen kannst.
- Hat die App es versucht? Suche im Anwendungslog nach dem Sendeversuch und jeder Ausnahme. Achte auf einen Job, der nie erstellt wurde, oft weil eine Bedingung oder ein Feature-Flag falsch war.
- Lief der Worker? Suche nach hängenden, fehlgeschlagenen oder wiederholten Jobs. Ein Queue-Worker, der nach einem Deploy nicht neu gestartet wurde, kann alten Code ausführen, und eine Wiederholungsregel kann Duplikate verschicken.
- Hat der Anbieter sie angenommen? Schlage den Empfänger oder die
Message-IDim Aktivitätslog deines Anbieters nach. Angenommen, aufgeschoben, zurückgewiesen und verworfen sind vier verschiedene Geschichten. - Wurde sie unterdrückt? Wenn diese Adresse schon einmal zurückgewiesen wurde oder sich beschwert hat, überspringen viele Anbieter künftige Sendungen stillschweigend. Das erwischt oft Tester, die eine alte Adresse wiederverwenden.
- Was hat der empfangende Server gesagt? Die Logs des Anbieters zeigen in der Regel die SMTP-Antwort, und dieser Text ist die nützlichste Zeile der ganzen Untersuchung.
- Stimmt DNS? Prüfe SPF, DKIM und DMARC für die tatsächliche Sende-Domain.
- Ist sie da, aber versteckt? Spam-Ordner, Tabs und Client-Filter kommen zuletzt, sobald ein Seed-Konto es dir zeigen kann.
Was dir die SMTP-Antwort sagt
Nach RFC 5321 ist eine Antwort, die mit 4 beginnt, ein vorübergehender Fehler, und der Absender sollte es später erneut versuchen. Eine Antwort, die mit 5 beginnt, ist dauerhaft. Die erweiterten Statuscodes aus RFC 3463 ergänzen danach Einzelheiten. Eine erfundene Logzeile könnte so aussehen, rein als Beispiel für das Format:
Nur ein Beispiel: to=user@gmail.example status=bounced reply="550 5.7.26 unauthenticated sender"
Lies sie von links nach rechts. Die 5 bedeutet, dass Wiederholungen nicht helfen. Die Familie 5.7 betrifft Sicherheit oder Richtlinien, was dich zu DNS und Signierung führt und weg von der Adresse des Empfängers. Die Tabelle unten gibt dir einen Ausgangspunkt für häufige Muster.
| Was du siehst | Wahrscheinlichste Schicht | Erste Stelle zum Nachsehen |
|---|---|---|
| Nichts im Log des Anbieters | App oder Warteschlange | Anwendungslogs und fehlgeschlagene Jobs |
| Anbieter meldet „dropped“ oder „suppressed“ | Unterdrückungsliste des Anbieters | Entferne die Testadresse oder nimm eine neue |
| Die API meldet Erfolg, aber nichts wird je als gesendet protokolliert | Sandbox-Modus noch aktiv | Einstellungen des Anbieters für diese Umgebung |
5.1.1 oder Ähnliches | Adresse des Empfängers | Tippfehler und Formularprüfungen, die die Adresse verändert haben |
5.7.26 bei Gmail | Authentifizierung | SPF, DKIM und Ausrichtung an der From-Domain |
4xx-Aufschübe, die sich nach einer Weile lösen | Empfänger bremst dich aus | Menge, Ruf oder eine neue Sende-IP |
| Bei einem externen Postfach zugestellt, bei Gmail fehlend | Richtlinie oder Filterung des Empfängers | Seed-Konten und Googles Richtlinien für Absender |
| Kommt an, aber der Link sagt „bereits verwendet“ | Scanner ruft den Link vorab ab | Tokens per POST einlösen, nicht per GET |
| Link führt zu einer Sicherheitswarnung | Klick-Tracking-Domain | Zertifikat der Tracking-Subdomain |
| Kommt doppelt an | Wiederholungslogik | Idempotenz der Jobs und die Timeouts, die Wiederholungen auslösen |
| Kommt sehr spät an | Warteschlange | Kapazität der Worker und ob Reset-Mails eine Warteschlange mit Massenmail teilen |
Die letzte Zeile ist ein Designpunkt, der einen Extrasatz wert ist. Teilen sich Passwort-Resets eine Warteschlange mit einem Newsletter-Versand, warten sie dahinter. Gib Transaktionsmails eine eigene Warteschlange und möglichst eine eigene Subdomain und einen eigenen Versandstrom, damit ein Marketingproblem keine Anmeldung verzögert.
Befehle, die die Suche abkürzen
Das meiste davon kannst du prüfen, ohne dein Terminal zu verlassen. Ersetze in diesen Beispielen die Beispielnamen durch deine eigenen.
dig +short MX example.comzeigt, wo eine Domain Mail empfängt. Eine leere Antwort braucht einen genaueren Blick, denn RFC 5321 lässt Absender auf einen Adresseintrag zurückfallen, während eine Antwort0 .ein Null-MX nach RFC 7505 ist, also bedeutet, dass die Domain überhaupt keine Mail annimmt.dig +short TXT example.comzeigt den SPF-Eintrag unter anderen Text-Einträgen.dig +short TXT selector._domainkey.example.comzeigt einen DKIM-Schlüssel. Nimm den echten Selector aus dem Werts=in der KopfzeileDKIM-Signatureder Nachricht.dig +short TXT _dmarc.example.comzeigt die DMARC-Richtlinie.openssl s_client -starttls smtp -connect smtp.example.com:587prüft, ob du dein Relay erreichst, und zeigt sein Zertifikat. Ein Fehler hier bedeutet ein Firewall- oder TLS-Problem, lange bevor es um Inhalt geht.swaks --to qa@example.test --from app@example.test --server localhost:1025sendet von Hand eine einfache Nachricht. Es umgeht deine App, sodass du erkennst, ob ein Problem an deinem Code oder an der Strecke liegt.
Für Belege auf Ebene der Kopfzeilen ist die verlässlichste Ansicht ein Postfach, das du bei einem großen Anbieter kontrollierst. Öffne in Gmail die Nachricht, nutze das Menü mit den drei Punkten und wähle Original anzeigen, was oben die Ergebnisse für SPF, DKIM und DMARC auflistet. Bedenke, dass das „bestanden“ eines Empfängers das eines anderen nicht garantiert.
Was bei jedem Ablauf zu prüfen ist
„Ist sie angekommen?“ ist die erste Frage und meist die uninteressanteste. Jeder Ablauf hat danach seine eigenen Wege, schiefzugehen.
Passwort zurücksetzen
Das OWASP Forgot Password Cheat Sheet ist die Referenz, auf der man hier aufbauen sollte. Es verlangt eine einheitliche Meldung, ob ein Konto existiert oder nicht, Antworten mit gleichmäßiger Dauer, Tokens, die zufällig, lang, sicher gespeichert und einmalig verwendbar sind, und Referrer-Policy: no-referrer auf der Reset-Seite.
- Die Anforderungsseite zeigt für registrierte und nicht registrierte Adressen dieselbe Meldung und braucht etwa gleich lang. Eine sofortige Antwort für unbekannte Adressen verrät so viel wie der Wortlaut.
- Der Link funktioniert einmal. Öffnest du ihn ein zweites Mal, bekommst du eine klare Erklärung mit der Möglichkeit, einen neuen anzufordern.
- Das Anfordern eines neuen Resets macht ältere Links ungültig, oder dein Design sagt absichtlich etwas anderes.
- Der Ablauf wird vom Server durchgesetzt und wurde durch Abwarten oder durch Ändern der Zeit in einer Testumgebung getestet.
- Ein erfolgreicher Reset sendet eine Bestätigungsmail, und andere Sitzungen werden nach deiner Richtlinie behandelt.
- Das Öffnen des Links ändert von allein nichts. Das Token wird beim Absenden des Formulars eingelöst.
- Die Reset-Seite schickt ihre URL nicht an Analysedienste oder Fehlertracking von Drittanbietern.
- Ratenlimits gelten pro Konto und pro IP, damit niemand das Postfach eines Fremden fluten kann.
- Adressen mit gemischter Groß- und Kleinschreibung oder Pluszeichen funktionieren wie einfache.
Registrierungs-Verifizierung
- Eine Registrierung sendet eine Nachricht, auch wenn der Job wiederholt wird.
- Der Link oder Code funktioniert einmal, und die Seite für abgelaufene Links zeigt einen Weg nach vorn.
- Ein erneutes Senden macht das vorherige Token ungültig oder besteht wie vorgesehen neben ihm und ist ratenbegrenzt.
- Unverifizierte Konten haben genau die Einschränkungen, die du beabsichtigt hast.
- Eine erneute Registrierung mit einer bereits registrierten Adresse verrät einem anonymen Besucher nicht, dass das Konto existiert, wenn dein Produkt das als sensibel behandelt. Ein gängiges Muster ist, stattdessen dem bestehenden Inhaber zu mailen.
- Der Link zeigt auf die richtige Umgebung. Eine Staging-Nachricht, die auf die Produktion verlinkt, ändert früher oder später Produktionsdaten.
Anmeldecodes und Magic Links
- Codes sind lang genug, laufen schnell ab und haben ein Versuchslimit.
- Magic Links zeigen eine Zielseite mit einem Button und lösen bei diesem POST ein, sodass das GET eines Scanners keinen Schaden anrichtet.
- Der Link auf einem anderen Gerät zu öffnen, tut, was dein Design sagt, und der Nutzer erkennt, was passiert ist.
- Die Betreffzeile enthält nur dann einen Code, wenn du entschieden hast, dass das akzeptabel ist, denn Benachrichtigungen zeigen ihn auf Sperrbildschirmen an.
Änderung der E-Mail-Adresse
- Die Bestätigung geht an die neue Adresse, und nichts ändert sich, bis sie bestätigt ist.
- Eine Mitteilung geht an die alte Adresse, damit der wahre Inhaber auf eine unbefugte Änderung reagieren kann.
- Offene Reset-Tokens funktionieren nach der Änderung nicht mehr.
- Mit zwei temporären Postfächern lässt sich das von Hand schnell durchspielen.
Einladungen, Quittungen und Benachrichtigungen
- Eine Einladung an eine Person ohne Konto führt zur Registrierung mit vorausgefüllter oder gesperrter Adresse, wie vorgesehen. Eine abgelaufene oder widerrufene Einladung sagt das.
- Eine Einladung kann nicht von einem anderen Konto angenommen werden, außer dein Design erlaubt es.
- Quittungen zeigen korrekte Beträge, Währungen, Daten und Zeitzonen für die Region des Nutzers, und Anhänge haben sinnvolle Namen und lassen sich richtig öffnen.
- Änderungen an den Einstellungen wirken beim nächsten Versand.
- Nicht wesentliche Mail hat eine funktionierende Abmeldung, und Konto- und Sicherheitspost ist klar getrennt. Unser Artikel zur Newsletter-Flut zeigt, wie das aus Sicht des Lesers aussieht.
- Übersetzte Vorlagen gibt es für jede unterstützte Sprache, mit korrektem Rechts-nach-links-Layout, wo es relevant ist, und ohne unübersetzte Bruchstücke im Betreff.
Den Token-Code prüfen
Das Testen über ein Postfach zeigt Verhalten. Ein kurzes Code-Review findet Designfehler, die kein Postfach zeigt. Achte beim Lesen des Codes hinter Reset, Verifizierung und Magic Links auf Folgendes.
- Die Zufallsquelle. Sie sollte ein kryptografisch sicherer Generator sein, etwa
secrets.token_urlsafe(32)in Python,crypto.randomBytes(32)in Node oderrandom_bytes(32)in PHP. Ein Zeitstempel, eine fortlaufende ID oder ein Hash der E-Mail ist nicht akzeptabel. - Länge. Link-Tokens tragen üblicherweise mindestens 128 Bit Zufall. Ein sechsstelliger Code ist nur bei knappem Ablauf und einem Versuchslimit in Ordnung.
- Speicherung. Speichere einen Hash des Tokens, damit ein Datenbankleck keine funktionierenden Reset-Links herausgibt.
- Vergleich. Nutze eine Funktion mit konstanter Laufzeit wie
hmac.compare_digest,hash_equalsodercrypto.timingSafeEqual, wo du geheime Werte direkt vergleichst. - Zweck. Ein Verifizierungs-Token darf nicht als Reset-Token funktionieren, und ein Token für ein Konto nicht für ein anderes.
- Ablauf. Der Server hält die Ablaufzeit, sie lässt sich also nicht durch Bearbeiten des Links ändern.
- Ungültigmachen. Die Verwendung des Tokens, eine Passwortänderung auf anderem Weg oder eine Änderung der E-Mail sollten alle offenen Tokens aufheben.
- Logging. Vollständige URLs mit Tokens sollten nicht in Anwendungslogs, Analyseereignisse oder Fehlertracker gelangen. Prüfe auch deine HTTP-Zugriffslogs.
Kopfzeilen und Authentifizierung
Öffne den Rohtext in einem Catcher, um zu sehen, was deine App erzeugt hat, und in einem Postfach, das du bei einem großen Anbieter kontrollierst, um zu sehen, was der Anbieter und das Netz hinzugefügt haben.
| Kopfzeile oder Element | Was zu prüfen ist |
|---|---|
From | Der richtige Markenname, auf einer Domain, die dir gehört und die du authentifizierst |
Reply-To | Ein überwachtes Postfach, oder mit Absicht weggelassen |
Return-Path | Die Bounce-Domain, ausgerichtet an deiner Domain, wenn du dich für DMARC auf SPF stützt |
DKIM-Signature | Vorhanden, mit einer d=-Domain, die sich an der From-Domain ausrichtet |
Message-ID | Vorhanden und eindeutig, da sie dein Schlüssel zur Nachverfolgung in den Logs des Anbieters ist |
Content-Type | multipart/alternative mit HTML- und Nur-Text-Teil |
List-Unsubscribe, List-Unsubscribe-Post | Bei Massen- und Werbemail vorhanden, mit Unterstützung der Abmeldung mit einem Klick nach RFC 8058 |
Auto-Submitted | auto-generated bei automatisierter Mail, wie in RFC 3834 definiert, um Antwortschleifen zu verhindern |
Einige Regeln, die du vor dem Release einer neuen Sende-Domain prüfen solltest. Eine SPF-Auswertung darf zehn DNS-Abfragen nicht überschreiten (RFC 7208), und das Limit zu überschreiten ist ein leichter Weg, nach dem Hinzufügen eines weiteren Anbieters zu deinem Eintrag zu scheitern. DKIM braucht den veröffentlichten und verifizierbaren Selector-Eintrag des Anbieters. DMARC braucht einen Eintrag auf deiner From-Domain, meist beginnend bei p=none mit eingeschalteten Berichten, und wird verschärft, sobald die Ausrichtung bestätigt ist.
Auch die Menge ändert die Regeln. Googles Richtlinien behandeln einen Absender ab etwa 5.000 Nachrichten pro Tag an persönliche Gmail-Konten als Massenversender, und Massenversender brauchen SPF, DKIM und DMARC, Abmeldung mit einem Klick bei Werbemail und eine von Nutzern gemeldete Spam-Rate unter 0,3 %, wobei 0,1 % das empfohlene Ziel ist. Andere Anbieter haben eigene Regeln. Amazon SES stellt ein Konto zum Beispiel bei einer Bounce-Rate von 5 % oder einer Beschwerderate von 0,1 % unter Überprüfung. Lies aktuelle Zahlen in der Dokumentation deines Anbieters nach, bevor du darauf planst, denn sie ändern sich.
Umgang mit Adressen und Validierung
Formulare lehnen gültige Adressen öfter ab, als man denkt, und ein vorgelagerter Validierungsfehler kann genau wie ein Zustellfehler aussehen. Teste deine damit.
| Eingabe | Erwarteter Umgang | Häufiger Fehler |
|---|---|---|
user+tag@example.com | Akzeptieren | Ein regulärer Ausdruck lehnt das Pluszeichen ab |
User@Example.COM | Akzeptieren und die Domain als nicht groß-/kleinschreibungsabhängig behandeln | Doppelte Konten, die sich nur in der Schreibweise unterscheiden |
o'brien@example.com | Akzeptieren | Abgelehnt, oder es bricht eine Abfrage oder Vorlage, wenn es nicht maskiert ist |
first.last@sub.example.co.uk | Akzeptieren | Die Validierung nimmt einen einzelnen Punkt in der Domain an |
| Leerzeichen am Anfang oder Ende | Zuerst entfernen | „Ungültige E-Mail“ bei korrekt eingefügter Adresse |
| Eine sehr lange Adresse | 64 Zeichen für den lokalen Teil und 254 insgesamt durchsetzen | Eine zu kurze Datenbankspalte schneidet sie stillschweigend ab |
| Internationalisierte Domains und Adressen | Einheitlich akzeptieren oder ablehnen, mit klarer Meldung | Ein Absturz bei Kodierung oder Logging |
| Eine Domain ohne Mail-Route | Warnen oder ablehnen | Ein Konto, das nie verifiziert werden kann |
Validiere im Formular großzügig und lass dann die Bestätigungsmail beweisen, dass die Adresse funktioniert. Ein strenger regulärer Ausdruck kostet dich echte Nutzer und sagt sehr wenig darüber, ob ein Postfach existiert.
Wenn dein Produkt in der Produktion Wegwerf-Domains ablehnt, braucht dein QA-Prozess auf Staging trotzdem einen Weg hindurch. Optionen sind eine Allowlist mit Testdomains außerhalb der Produktion, ein Flag, das die Prüfung in Testumgebungen abschaltet, oder deine eigene Testdomain. Schwäche die Produktionsregel nicht ab, um das Testen zu erleichtern. Und wenn du erst entscheidest, ob du diese Regel überhaupt willst, legt unser Beitrag dazu, warum Websites Wegwerf-E-Mail blockieren, Kosten und Nutzen aus Sicht eines Betreibers dar.
Wie es dargestellt wird
Bei der Darstellung hilft die Durchsicht durch einen Designer am meisten, und sie braucht echte Nachrichten in echten Clients.
- Der Nur-Text-Teil liest sich gut und enthält den vollständigen Link. „Klicke auf den Button unten“ ist dort nutzlos.
- Der Dunkelmodus lässt Logos sichtbar und hält den Kontrast. VookMail hat einen Dunkelmodus, was ein Anfang ist, und die Clients, die deine Nutzer bevorzugen, sind der eigentliche Test.
- Bei blockierten Bildern ist der Handlungsaufruf weiterhin ein echter Textlink oder ein HTML-Button.
- Buttons sind groß genug zum Antippen, und lange URLs sprengen kein Handy-Layout.
- Der Vorschautext ist mit Absicht geschrieben, ohne übrig gebliebene Formulierungen der Vorlage.
- Überschriften sind semantisch, der Kontrast reicht, Linktexte sind aussagekräftig, und das HTML hat ein Sprachattribut.
- Fehlende Daten erzeugen kein „Hallo {first_name}“ oder „Hallo ,“.
- Die Nachrichtengröße bleibt deutlich unter etwa 102 KB, dem Punkt, an dem Gmail nach weit verbreiteten Berichten lange Nachrichten abschneidet. Das Abschneiden kann deinen Fußbereich und einen Abmelde-Link im Text verbergen.
Schutzvorkehrungen gegen Unfälle
Peinliche E-Mail-Vorfälle sind meist Konfigurationsfehler: Staging-Mail, die echte Kunden erreicht, Produktion mit einem Testschlüssel, Links auf localhost. Einige Einstellungen verhindern die meisten davon.
Halte pro Umgebung getrennte Zugangsdaten bereit, in Umgebungsvariablen oder einem Secret-Manager. Nutze außerhalb der Produktion eine Empfänger-Allowlist, damit der Mailer nur an freigegebene Testdomains zustellt und alles andere umleitet oder verwirft. Baue jeden Link aus einer einzigen Einstellung wie APP_URL, damit Vorlagen keine fest eingetragenen Hosts enthalten. Setze vor die Betreffzeilen außerhalb der Produktion etwas wie [STAGING], damit eine fehlgeleitete Nachricht dem Empfänger sofort auffällt.
Wenn du Produktionsdaten nach Staging kopierst, ersetze jede echte Adresse durch eine synthetische, bevor ein Mail-Worker startet. Die Reihenfolge zählt, denn ein Worker, der zuerst startet, kann sofort anfangen, geplante Mail abzuarbeiten. Und verfolge den Sandbox-Modus für jede Umgebung bewusst. Mit einer Produktion zu starten, die noch in der Sandbox steckt, ist ein Klassiker: Die API meldet Erfolg, die Logs sehen sauber aus, und es geht keine Mail raus.
Automatisierte Suiten sollten auf Infrastruktur bleiben, die du kontrollierst
Ein öffentliches temporäres Postfach ist die falsche Abhängigkeit für CI. Die Webseite eines anderen auszulesen ist brüchig, und deine Builds würden aus Gründen scheitern, die mit deinem Code nichts zu tun haben. Es legt auch deinen Testverkehr auf einen Dienst, den du nicht betreibst. Nachrichten dort kann jeder lesen, der die Adresse hat, also sollte nichts Automatisiertes davon abhängen.
Eine sinnvolle Anordnung sieht so aus. Framework-Helfer prüfen, dass die richtige Mail angefordert wird. Ein Mailpit-Container in deinem Test-Stack empfängt die echte Nachricht, und dein Test liest sie über die HTTP-API von Mailpit (GET /api/v1/messages), zieht den Link heraus und folgt ihm. Der Testmodus des Anbieters prüft Webhooks und Fehlerbehandlung. Ein nächtlicher Job auf deiner eigenen Testdomain sendet über den echten Anbieter und liest das Ergebnis über einen eingehenden Webhook, sodass du täglich ein Signal bekommst, dass die echte Zustellung weiter funktioniert.
Temporäre Mail gehört in die menschlichen Teile des Testens: explorative Sitzungen, in denen du schnell eine frische Identität brauchst, ein Smoke-Test vor dem Release, das Nachstellen der Meldung eines Nutzers, Text- und Design-Reviews und das Testen auf einem Handy. Für Letzteres bringt der QR-Button oder die App von Google Play oder der Huawei AppGallery das Postfach auf ein Testgerät. Prüfe, dass Links deine App öffnen, wenn sie installiert ist, und auf eine funktionierende Webseite zurückfallen, wenn nicht, und dass die App den verifizierten Status bemerkt, ohne eine neue Anmeldung zu verlangen.
Ein Testfall, der eine Übergabe übersteht
Einheitliche Testfälle lassen sich bei jedem Release leichter wiederholen und zwischen Testern weitergeben. Dieses Beispiel enthält die Felder, auf die es meist ankommt.
| Feld | Beispiel |
|---|---|
| Test-ID | EMAIL-RESET-03 |
| Ablauf | Passwort zurücksetzen, Wiederverwendung des Tokens |
| Voraussetzungen | Verifiziertes Testkonto auf Staging, mit einer frischen temporären Adresse |
| Schritte | Einen Reset anfordern, den Link öffnen, ein neues Passwort setzen, denselben Link noch einmal öffnen |
| Erwartetes Ergebnis | Die zweite Verwendung erklärt, dass der Link nicht mehr gültig ist, und bietet eine neue Anforderung an |
| Belege | Screenshots, Message-ID, falls vorhanden, Zeitstempel, verwendete Adresse |
| Umgebung | Build-Nummer von Staging und Mail-Konfiguration |
Die Test-ID in den Benutzernamen zu setzen, wie in email-reset-03-x7, verknüpft jedes Postfach mit seinem Fall und verhindert, dass zwei Tester über eine Adresse kollidieren. Der kurze zufällige Zusatz ist da, weil jeder ein Postfach öffnen kann, wenn er den Namen errät.
Was du nicht an ein öffentliches Postfach schicken solltest
Behandle jedes temporäre Postfach als für jeden lesbar, der die Adresse kennt, und teste entsprechend.
- Sende nur synthetische Daten: falsche Namen, falsche Bestellungen, falsche Adressen. Echte Kundendaten gehören nicht dorthin, und je nachdem, wo du tätig bist, kann das Senden auch ein rechtliches Problem für dich schaffen.
- Sende nie API-Schlüssel, Datenbank-Zugangsdaten oder Admin-Einladungen für echte Systeme.
- Lösche Testkonten regelmäßig, besonders privilegierte. Ein Admin-Testnutzer, der an ein öffentliches Postfach geknüpft ist, ist ein Zugang, wenn jemand anderes dieses Postfach öffnet und einen Reset anfordert. Da die Adresse nach dem Leeren nicht für dich reserviert ist, bleibt dieses Risiko nach dem Test bestehen.
- Nutze nie eine temporäre Adresse als Inhaber eines echten Produktionskontos oder eines Dienstes von Drittanbietern, auf den sich deine Firma verlässt.
- Kenne die Aufbewahrungsfrist. Nachrichten und Anhänge verschwinden nach etwa einem Tag, und die Datenschutzerklärung hat die Einzelheiten.
Das Testen des eigenen Produkts ist einer der klarsten legitimen Einsatzzwecke für Wegwerf-E-Mail. Halte es so: Teste Systeme, die dir gehören oder die du testen darfst. Nutze temporäre Postfächer nicht, um entgegen den Bedingungen Konten bei Diensten anderer Firmen anzulegen, um Testzeiträume einzusammeln oder um das Anmeldeformular eines anderen einem Lasttest zu unterziehen. Die Allgemeinen Geschäftsbedingungen regeln die zulässige Nutzung, und die Methodik-Seite erklärt, wie der Dienst funktioniert. VookMail gehört zum PAYATE-Netzwerk kostenloser Tools.
Vor dem Release
- SPF, DKIM und DMARC sind für die tatsächliche Sende-Domain der Produktion verifiziert, die
From-Domain ist ausgerichtet. - Der Produktions-Mailer läuft mit Produktions-Zugangsdaten, der Sandbox-Modus ist aus, bestätigt durch eine echte Nachricht.
- Die Registrierungs-Verifizierung kam bei einer frischen externen Adresse an, der Link wurde einmal verwendet, der Ablauf getestet.
- Der Passwort-Reset wurde Ende-zu-Ende getestet, einschließlich identischer Antworten für unbekannte Adressen und der Bestätigungsnachricht.
- Reset- und Magic-Link-Tokens werden bei einem Formular-Absenden eingelöst, sodass das GET eines Scanners sie nicht verbraucht.
- Die Änderung der E-Mail sendet sowohl an die neue als auch an die alte Adresse.
- Alle Links zeigen per HTTPS auf den Produktions-Host, auch die vom Klick-Tracking umgeschriebenen.
- Transaktionsmail ist von Massenmail getrennt, mindestens in der Warteschlange.
- HTML und Nur-Text sind beide vorhanden und lesbar, Dunkelmodus und blockierte Bilder sind geprüft.
- Eine Prüfung der Platzierung bei Seed-Konten, falls sich Domain oder Vorlage deutlich geändert haben.
- Die Abmeldung funktioniert bei nicht wesentlicher Mail, und übersetzte Vorlagen sind geprüft.
- Belege hängen am Release-Ticket, und die Zahlen zu Bounces und Beschwerden stehen auf einem Dashboard, das nach dem Start jemand beobachtet.
Fragen, die Entwickler dazu stellen
Ein echtes Postfach hat meine Mail angenommen. Bin ich bei Gmail sicher?
Nein. Die Zustellung an eine Domain zeigt, dass deine Nachricht abgegangen ist, eine Route fand und dort angenommen wurde. Gmail wendet eigene Regeln zur Authentifizierung und Filterung an, ebenso jeder andere große Anbieter. Nutze für diese Frage Seed-Konten und Googles Postmaster Tools.
Kann ich dieselbe Testadresse wiederverwenden?
Innerhalb einer Sitzung ja, aber eine frische Adresse ergibt einen saubereren Test. Alte Adressen sammeln Einträge auf Unterdrückungslisten und alte Nachrichten, und bei einem temporären Dienst wird das Postfach ohnehin nach etwa einem Tag geleert.
Mail kommt bei meinem Catcher an, aber nicht extern. Wo fange ich an?
Ein Catcher zeigt, dass deine App eine Nachricht erzeugt hat, und nicht mehr, beginne also mit dem Aktivitätslog des Anbieters. Meistens lautet die Antwort: eine Sandbox-Einstellung, ein Eintrag auf der Unterdrückungsliste, falsche Zugangsdaten oder eine SMTP-Ablehnung, die die Authentifizierung nennt.
Wie lange sollte ein Reset-Link gültig bleiben?
Kurz genug, um Schaden zu begrenzen, und lang genug, damit langsame Mail ankommt. Viele Teams landen irgendwo zwischen 15 Minuten und einer Stunde, doch es hängt von deinem Risiko ab und davon, wie schnell deine Mail zugestellt wird, und die Mail deiner Nutzer kann sich außerhalb deiner Kontrolle verzögern. Was auch immer du wählst, teste den abgelaufenen Zustand und sage den Leuten, was sie als Nächstes tun sollen.
