Proszę o link do logowania
Wpisuję e-mail na /login, widzę „Sprawdź pocztę” i przycisk „[DEV] Symuluj kliknięcie w link”.
useState. Pole tylko ją pokazuje (value) i zgłasza zmiany (onChange). Dzięki temu w każdej chwili masz e-mail w zmiennej, bez czytania z DOM.preventDefault()Formularz HTML domyślnie wysyła się i przeładowuje stronę. W SPA tego nie chcemy, więc w onSubmit blokujemy domyślne zachowanie i robimy wszystko sami.noValidateWyłącza dymki walidacji przeglądarki (różne w każdej przeglądarce). Błąd pokazujemy sami pod polem, w stylu aplikacji.navigate(…, { state })Przekazuje dane do następnej strony bez umieszczania ich w adresie. Znikają po odświeżeniu, dlatego strona docelowa musi obsłużyć ich brak.usedAt. Kto ma link, ten się loguje, ale tylko raz i tylko przez chwilę.verifyToken w sesji 17.Najpierw napraw dane przykładowe
seed.js ma tablicę magicLinks, a kod logowania używa db.loginTokens (tak jak tabela login_tokens w bazie). Bez poprawki requestMagicLink rzuci „Cannot read properties of undefined (reading 'push')”.Zmieniłeś kształt danych, a w przeglądarce leży stara wersja z magicLinks. Dlatego podbij wersję klucza: stary zapis zostanie zignorowany i baza wypełni się od nowa.
„Serwer”: zapisz token i zwróć link
Masz już ten plik, ale w starszej wersji: zakłada konto od razu przy prośbie o link. Zamień go w całości na wersję poniżej.
@, coś, kropka, coś. Nie musi łapać każdego dziwnego adresu, ma odsiać literówki. Prawdziwy test to i tak to, czy mail dojdzie.Date.now()). Zapis jako mnożenie czyta się jak „15 minut”.= {} sprawia, że można wywołać requestMagicLink(email) bez drugiego argumentu.catch i pokaże message.Math.random().login_tokens. Zapisujemy e-mail i imię, ale nie zakładamy konta.token=…&next=… i sam koduje znaki specjalne. Ręczne sklejanie napisów psuje się na & albo ? w danych./. Chroni przed „open redirect”: linkiem, który po zalogowaniu wyrzuca na obcą stronę.Fasada api/auth.js ze specyfikacją
Dziś plik ma export * from './mock/auth.js'. Zamień to na jawną listę: komentarz jest specyfikacją przyszłego backendu (adres i co zwraca), a jawny eksport pilnuje, żeby strony używały tylko tego, co jest w specyfikacji.
Strona logowania
Zamień szkielet z TODO na formularz. Na razie bez sprawdzania, czy ktoś jest już zalogowany (nie ma jeszcze useAuth) i bez konta demo.
RequireAuth.async, bo czekamy na „serwer” (await requestMagicLink). Funkcja w środku komponentu widzi aktualne email i name.apiError trafia do catch, a jego message pod pole. Przycisk odblokowujemy tylko przy błędzie; przy sukcesie i tak zmieniamy stronę.devLink bez wpisywania ich w adres.as, więc sama staje się elementem <form>. Jeden znacznik mniej, a onSubmit i noValidate przechodzą przez ...rest.Input przez FormField pokazuje błąd pod polem i ustawia aria-invalid. To praca z etapu 10, która teraz się zwraca.Button ma domyślnie type="button". Tutaj musi być submit, żeby Enter w polu i kliknięcie wysyłały formularz.Strona „Sprawdź pocztę”
LoginPage przekazała w navigate.?. nie wywala się, gdy state jest null. Tak jest po odświeżeniu albo po wpisaniu adresu ręcznie. Wtedy pokazujemy prośbę o ponowne wpisanie e-maila.Link zmienia stronę bez przeładowania. Link z maila otworzy się jako pełne wejście, ale w SPA wynik jest ten sam.{' '} wstawia ją jawnie przed linkiem.Podepnij trasy
Gotowe, gdy
- Pusty i błędny e-mail pokazują czerwony błąd pod polem.
- Poprawny e-mail prowadzi na
/login/sprawdz-pocztez Twoim adresem i przyciskiem [DEV]. - W DevTools → Application → Local Storage →
pettrace:db:v2wloginTokensjest token z Twoim e-mailem iexpiresAtza 15 minut. - Nowy adres nie pojawia się w
users. - Odświeżenie „Sprawdź pocztę” pokazuje „Wróć do logowania”.
- Przycisk [DEV] prowadzi na razie na placeholder „Weryfikacja logowania”. To normalne, stronę zrobisz w sesji 17.