E-mail do resetowania hasła to klucz uniwersalny do Twojego produktu. Każdy, kto może go przeczytać, może przejąć konto, dlatego atakujący biorą go na cel, a użytkownicy nauczyli się podchodzić do niego podejrzliwie.
Dobry proces resetowania musi być na tyle bezpieczny, by oprzeć się atakującym, i na tyle czytelny, by prawdziwi użytkownicy zaufali mu w kilka sekund. Ten poradnik omawia oba aspekty, od chwili kliknięcia „Nie pamiętasz hasła?” aż po e-mail z potwierdzeniem zmiany.
Proces w skrócie
- Użytkownik wpisuje swój adres e-mail na stronie Nie pamiętasz hasła.
- Twoja aplikacja zawsze pokazuje ten sam komunikat, niezależnie od tego, czy konto istnieje.
- Jeśli istnieje, tworzysz jednorazowy token i wysyłasz e-mailem link do resetowania.
- Użytkownik otwiera link, ustawia nowe hasło, a token zostaje zużyty.
- Wylogowujesz pozostałe sesje użytkownika i wysyłasz e-mail „Twoje hasło zostało zmienione”.
Krok 1: Nie zdradzaj, kto ma konto
Po wysłaniu formularza zawsze odpowiadaj tym samym tekstem:
Jeśli istnieje konto dla adresu ada@example.com, wysłaliśmy link do zresetowania hasła. Wygaśnie za 30 minut.
Komunikat „Brak konta z tym adresem e-mail” mówi każdemu, kto ma listę adresów, dokładnie które z nich korzystają z Twojego produktu. Zadbaj też o podobny czas odpowiedzi: wyszukiwanie konta i wysyłkę e-maila wykonuj w tle, aby dla nieznanych adresów strona nie odpowiadała zauważalnie szybciej.
Krok 2: Utwórz silny, jednorazowy token
Token w linku musi być długi, losowy i niemożliwy do odgadnięcia:
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
});
Zasady:
- Przechowuj tylko skrót tokenu, aby wyciek bazy danych nie rozdawał działających linków resetujących.
- Jeden aktywny token na użytkownika. Wydanie nowego zastępuje stary.
- Krótka ważność: typowo od 15 do 60 minut.
- Jednorazowe użycie. Usuń token, gdy tylko hasło zostanie zmienione.
- Unieważnij go, jeśli w międzyczasie użytkownik zaloguje się pomyślnie lub zmieni adres e-mail.
Krok 3: Wyślij e-mail natychmiast
Użytkownik czeka, więc wysyłaj w ramach żądania, a nie w zadaniu wsadowym:
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()
Wysyłaj go z osobnego, uwierzytelnionego adresu, np. security@yourco.com. W Inbixio podłącz tę skrzynkę jako osobny serwer pocztowy i daj usłudze uwierzytelniania klucz API przypięty do niego, aby e-maile resetujące przychodziły z adresu, którego użytkownicy się spodziewają. Jeśli kiedykolwiek usuniesz ten serwer, przypnij klucz ponownie. Jak to skonfigurować, przeczytasz w artykule bezpieczeństwo kluczy API.
Krok 4: Napisz e-mail, któremu ludzie ufają
E-maile phishingowe podszywają się pod resety haseł częściej niż pod jakąkolwiek inną wiadomość. Spraw, by Twój był nie do pomylenia:
- Temat: prosty i konkretny, np. „Zresetuj hasło do YourApp”. Bez presji czasu i wykrzykników.
- Jeden wyraźny przycisk oraz pełny link jako tekst dla klientów, które blokują przyciski.
- Czas ważności: „Ten link wygaśnie za 30 minut”.
- Kontekst: kiedy wysłano prośbę i, jeśli masz te dane, z jakiej przeglądarki lub miasta.
- Co zrobić, jeśli to nie on: „Jeśli nie prosiłeś o zresetowanie hasła, zignoruj tę wiadomość. Twoje hasło się nie zmieni”.
- Żadnych innych linków, obrazków ani promocji. Im mniej linków, tym łatwiej zweryfikować wiadomość.
<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>
Krok 5: Ostrożnie obsłuż link
Gdy użytkownik otwiera link:
- Wyszukaj skrót tokenu, sprawdź, czy nie wygasł, i pokaż formularz „nowe hasło”. Jeszcze nie loguj użytkownika.
- Nie przekazuj tokenu w żądaniach do stron trzecich. Dodaj
<meta name="referrer" content="no-referrer">do strony resetowania i nie ładuj na niej skryptów analitycznych ani reklamowych, aby token z adresu URL nie wyciekł przez nagłówki referrer. - Po wysłaniu formularza sprawdź nowe hasło pod kątem Twoich zasad dotyczących haseł, zahaszuj je wolnym algorytmem (bcrypt, scrypt lub Argon2), usuń token i wyloguj wszystkie pozostałe sesje.
Krok 6: Potwierdź zmianę
Po zmianie hasła zawsze wysyłaj krótkie potwierdzenie:
Hasło do Twojego konta YourApp zostało zmienione 28 października o 14:32 UTC. Jeśli to Ty, nie musisz nic robić. Jeśli nie, natychmiast zabezpiecz swoje konto.
Ten e-mail to dzwonek alarmowy dla użytkownika, jeśli do konta dostał się ktoś inny, więc nigdy go nie pomijaj.
Upewnij się, że dociera
E-mail resetujący w folderze spamu to zgłoszenie do supportu. Przed startem:
- skonfiguruj SPF, DKIM i DMARC dla domeny nadawczej,
- przetestuj na adresach Gmail i Outlook i sprawdź, czy nagłówki pokazują PASS,
- po wdrożeniu obserwuj wskaźnik Failed Deliveries (nieudane dostarczenia) w panelu Inbixio.
Checklista
- Ta sama odpowiedź dla istniejących i nieznanych adresów
- 32-bajtowy losowy token, przechowywany tylko jego skrót
- Ważność 15–60 minut, jednorazowe użycie, jeden aktywny token na użytkownika
- Wysyłka natychmiastowa z osobnego, uwierzytelnionego adresu nadawcy
- Czytelny szablon: jeden przycisk, zwykły link, czas ważności, zdanie „to nie Ty?”
- Brak skryptów stron trzecich na stronie resetowania; referrer wyłączony
- Pozostałe sesje wylogowane i e-mail z potwierdzeniem wysłany po zmianie
Wyślij to przez Inbixio
Podłącz własny serwer SMTP, utwórz klucz API z ograniczonymi uprawnieniami i wysyłaj z dowolnego języka jednym żądaniem HTTPS.