CeníkAPI & SMTPŘešeníSrovnáníNástrojeBlogFAQKontakt
PřihlásitRegistrovat
Tmavý režim
← Zpět na blog
26. října 2026·5 min čtení·Tým TopEmail

Reset hesla e-mailem bezpečně: jednorázový token, expirace, rate limit a co napsat do zprávy

Kontrolní seznam pro obnovu hesla přes e-mail: náhodný token uložený jako hash, krátká platnost, jedno použití, stejná odpověď pro existující i neexistující účet, omezení pokusů, odkaz vs. kód a text e-mailu, který neskončí ve spamu.

Reset hesla je nejcitlivější e-mail, který aplikace posílá: kdo ho zachytí nebo vyvolá, získá účet. Přitom je to jedna z prvních funkcí, které vývojář napíše, často večer před spuštěním. Správná implementace má šest pravidel a žádné z nich není složité; tady jsou v pořadí, v jakém se na nich nejčastěji chybuje.

1. Token: dlouhý, náhodný, uložený jako hash

Odkaz pro reset obsahuje token, který je jediným důkazem, že žadatel má přístup ke schránce. Proto:

  • Alespoň 32 bajtů z kryptografického generátoru: crypto.randomBytes(32) v Node.js, random_bytes(32) v PHP, secrets.token_urlsafe(32) v Pythonu. Nikdy ID uživatele, časové razítko, ani jejich hash; obojí lze odhadnout.
  • Do databáze ukládejte hash tokenu (SHA-256 stačí, token má dost entropie), ne token samotný. Pokud unikne databáze nebo logy, útočník nemá platné odkazy.
  • K hashi uložte user_id, created_at, expires_at, used_at a případně IP a user agent žádosti.
  • Porovnávejte v konstantním čase (hash_equals(), crypto.timingSafeEqual()), i když u 256bitového tokenu je riziko časového útoku spíš teoretické.

Token patří do cesty nebo query odkazu, ne do uživatelského jména, a odkaz by měl vést na stránku, která token nikam dál nepošle: nastavte na ní Referrer-Policy: no-referrer, nenačítejte na ní cizí skripty ani obrázky z externích domén, aby token neodtekl v hlavičce Referer.

2. Platnost: krátká, jednorázová, poslední vyhrává

  • 15 až 60 minut. Reset hesla uživatel dělá teď, ne zítra. Hodina pokryje zpožděný e-mail i hledání ve spamu; delší platnost rozšiřuje okno pro zneužití.
  • Jedno použití. Po nastavení hesla označte token jako použitý a všechny ostatní nevyužité tokeny stejného uživatele zneplatněte.
  • Nový token zneplatní starý. Když uživatel klikne „poslat znovu", starý odkaz přestane platit. Jinak platí dva a schránka plná starých e-mailů je sbírka klíčů.
  • Po změně hesla ukončete ostatní přihlášení (invalidujte session i refresh tokeny). Smysl resetu často je vyhodit někoho, kdo se do účtu dostal.

3. Neprozrazujte, zda účet existuje

Formulář „zapomenuté heslo" musí odpovědět stejně pro registrovanou i neregistrovanou adresu:

Pokud u nás máte účet s touto adresou, poslali jsme vám odkaz pro nastavení nového hesla. Zkontrolujte i složku spam.

Jakmile odpovíte „tato adresa není registrována", máte veřejný nástroj na ověřování, kdo je vaším zákazníkem. Stejně se chovejte v časování odpovědi (odesílání e-mailu dělejte asynchronně, aby nebyla registrovaná adresa poznat podle pomalejší odpovědi) a v API: stejný stavový kód, stejné tělo.

Na neexistující adresu neposílejte nic. Některé velké služby posílají i e-mail „někdo žádal o reset, ale účet s touto adresou nemáme"; pro většinu aplikací je to zbytečný e-mail navíc a potenciální cesta ke spamu přes váš formulář.

4. Rate limit na tři úrovně

Formulář pro reset je veřejný endpoint, který na požádání posílá e-maily. Bez omezení z něj kdokoli udělá nástroj na zahlcení cizí schránky, a vy za každý e-mail platíte a sbíráte stížnosti. Omezte:

  1. Na účet: maximálně 3 až 5 žádostí za hodinu. Další žádosti tiše ignorujte (odpověď zůstává stejná).
  2. Na IP adresu: desítky žádostí za hodinu přes různé adresy jsou skript, ne zákazník.
  3. Na ověření tokenu: po několika neplatných tokenech z jedné IP zpomalte nebo zablokujte; u 256bitového tokenu hádání nehrozí, ale zbytečně zatěžuje databázi a logy.

Pokud používáte CAPTCHA, dejte ji až po překročení limitu, ne na první pokus; člověk, který zapomněl heslo, má už tak špatný den.

5. Odkaz nebo kód

Odkaz je výchozí volba: jedno kliknutí, token se nepřepisuje, funguje na všech zařízeních. Má dvě slabiny: bezpečnostní brány u firemních příjemců odkazy preventivně otevírají (proto nikdy neměňte heslo ani nezneplatňujte token na GET, ale až na odeslání formuláře), a odkaz nefunguje, když uživatel čte e-mail na jiném zařízení, než kde se přihlašuje.

Kód (6 až 8 číslic opsaných do formuláře) řeší druhé zařízení a obchází brány, ale potřebuje vlastní rate limit na pokusy, protože kombinací je málo. Pravidla pro kódy jsou v článku o ověřovacím kódu e-mailem.

Rozumný kompromis: odkaz, který obsahuje token, a pod ním stejný token zobrazený jako kód pro ruční opsání. Nebo nabídnout obojí a nechat uživatele vybrat.

6. Co napsat do e-mailu

Reset hesla je zároveň nejčastější námět phishingu, takže váš e-mail musí být rozpoznatelný jako pravý a nesmí učit zákazníky klikat na cokoli.

Předmět: konkrétní a klidný. „Nastavení nového hesla k účtu Firma" ano; „URGENT: Your account will be deleted" ne. Předmět, který vzbuzuje paniku, je přesně to, co dělá phishing, a filtry to vědí.

Tělo:

  • Co se stalo: „Někdo (nejspíš vy) požádal o nastavení nového hesla k účtu na firma.cz pro adresu jan@…".
  • Jedno tlačítko nebo odkaz s viditelnou plnou adresou na vaší doméně; žádné zkracovače, žádné sledovací přesměrování přes cizí doménu.
  • Doba platnosti: „Odkaz platí 30 minut a lze ho použít jednou."
  • Co dělat, když to nebyl uživatel: „Pokud jste o změnu nežádali, nic se nestalo a heslo zůstává stejné. Tento e-mail můžete smazat." Nepřidávejte odkaz „nahlásit"; další odkaz je další příležitost pro phishing.
  • Odesílatel s jménem vaší služby a adresou na ověřené doméně (ucet@firma.cz), ne noreply@ na doméně poskytovatele.

Co do e-mailu nepatří: heslo (ani dočasné), uživatelské jméno v kombinaci s odkazem, reklama, odhlašovací odkaz (není z čeho se odhlásit), a žádné přílohy.

Po úspěšné změně pošlete druhý e-mail: „Heslo k vašemu účtu bylo změněno dne … z IP …. Pokud to nebyli vy, kontaktujte nás." Tenhle e-mail je často jediný způsob, jak se oběť o převzetí účtu dozví.

Doručitelnost: reset musí dojít hned

Uživatel sedí u formuláře a čeká. Reset, který dorazí za 20 minut nebo skončí ve spamu, je z pohledu zákazníka nefunkční funkce a z pohledu podpory ticket. Proto:

  • posílejte z ověřené domény se SPF, DKIM a DMARC, ne z webového serveru přímo,
  • posílejte přes frontu asynchronně, ale bez zbytečné prodlevy; uživatelský dotaz nesmí čekat na SMTP,
  • sledujte u těchto e-mailů stav delivered a bounced přes webhook; u bounced zobrazte uživateli na stránce, že adresa není dostupná, a nabídněte podporu,
  • označte je značkou (type=password-reset), abyste je v doručenkách odlišili od ostatních a viděli jejich doručitelnost zvlášť.

Shrnutí

  • Token 32+ bajtů z CSPRNG, v databázi jen hash, odkaz bez úniku přes Referer.
  • Platnost 15 až 60 minut, jedno použití, nový zneplatní starý, po změně hesla odhlásit všude.
  • Stejná odpověď bez ohledu na existenci účtu, včetně časování.
  • Rate limit na účet, IP i ověření tokenu.
  • Odkaz jako výchozí, kód jako doplněk; heslo se nikdy nemění na GET.
  • E-mail: klidný předmět, jeden odkaz na vlastní doméně, doba platnosti, co dělat, když to nebyl uživatel, a potvrzení po změně.

Reset hesla je typický transakční e-mail, který zákazník čeká a který musí dorazit do minuty. Přes TopEmail jde posílat z vaší domény přes API i SMTP relay; cena je stejná jako u ostatních e-mailů, viz ceník.

bezpečnostimplementaceOTPšablony
Transakční e-maily z vaší domény

Transakční e-maily z vaší domény přes API nebo SMTP, od 0,025 do 0,06 Kč za e-mail podle objemu, prvních 1 000 e-mailů měsíčně zdarma. Registrace zdarma, bez platební karty.

Registrovat zdarma →