Magic link - logowanie bez hasła
Podczas tworzenia hobbystycznego projektu stanąłem w końcu przed klasycznym elementem serwisów internetowych, czyli logowaniem i rejestracją. Tym razem postanowiłem zrobić to zupełnie inaczej - bez haseł.
Krótko o magic link
Nie jestem w stanie sobie przypomnieć, ile razy tworzyłem konta w różnych serwisach tylko po to, żeby wejść, skonfigurować coś, zapomnieć i wrócić za kilka miesięcy… nie pamiętając hasła.
Na ciekawe rozwiązanie tego problemu, często nazywanym magic link wpadłem przypadkowo kilka lat temu podczas używania usługi ImprovMX. Na początku byłem lekko zdziwiony “że jak to tak bez podawania hasła”. Jednak po kilkukrotnym odwiedzeniu tej strony doceniłem logowanie przez link. Tutaj nie musiałem nic zapamiętywać. Wpisałem adres e‑mail, kliknąłem link i gotowe.
Magic link to mechanizm, dzięki któremu do logowania potrzebujemy tylko adresu e‑mail. Kiedy użytkownik chce wejść do serwisu, wpisuje swój adres, a następnie otwiera wygenerowany przez serwis link, który pozwoli mu na uzyskanie dostępu.
Zalety i wady dla użytkownika
Patrząc z perspektywy zwykłego użytkownika, najbardziej doceniam:
- brak konieczności wymyślania kolejnego hasła (w końcu lepiej nie powtarzać tych samych haseł w różnych miejscach)
- brak konieczności przypominania sobie hasła po dłuższej nieobecności
- zero obaw dotyczących wycieku hasła
Oczywiście są też i minusy tego rozwiązania:
- wpisanie hasła jest o wiele szybsze niż otworzenie e-maila i kliknięcie linka. Jest to irytujące podwójnie na telefonie, gdzie aplikacja poczty otwiera stronę pozostając nadal w swoim kontekście
- w przypadku braku dostępu do skrzynki pocztowej (np. awaria po stronie Gmaila) nie można się zalogować
- nie dla każdego użytkownika taki mechanizm jest zrozumiały, część osób może zwyczajnie odpuścić sobie korzystanie z serwisu
Niektórzy mogliby jeszcze podnieść, że włamanie na pocztę umożliwia włamanie się na konto w serwisie. Jest to oczywiście prawda, ale w przypadku zwykłego logowania hasłem nie jest inaczej. Trzeba zrobić tylko jeden krok więcej: zgłosić, że zapomniało się hasła i je zresetować. Pozwolę więc sobie stwierdzić, że:
Logowanie przez link jest tak samo bezpieczne, jak przypominanie hasła w tradycyjnym modelu.
Zalety i wady dla developera
Oprócz punktu widzenia zwykłego użytkownika powinniśmy zabrać pod uwagę także to, czy takie rozwiązanie przyniesie jakąś wartość dla naszej aplikacji od strony implementacji.
Zalet jest naprawdę sporo:
- nie ma możliwości wycieku haseł
- odchodzi cała otoczka związana z przechowywaniem haseł
- nie trzeba implementować: aktywacji konta (samo odebranie linka do logowania jest potwierdzeniem), przypominania/resetu hasła, zmiany hasła. Jest to oszczędność kilku widoków oraz dodatkowych szablonów e-maili
- uproszczone formularze logowania i rejestracji poprzez pominięcie m.in. walidacji hasła, komunikatu o niepoprawnym haśle lub e-mailu, zabezpieczenia przed próbą brute force itd.
Natomiast do głowy przychodzi mi tylko jeden minus i to trochę naciągany:
- trzeba podpiąć wysyłkę e-maili. Do logowania hasłem nie jest to wymagane, chociaż zwykle i tak się to implementuje (aktywacja konta, zmiana hasła - to wszystko wymaga wysyłania wiadomości)
Magic link od strony technicznej
Na początku chciałbym przypomnieć ważną rzecz:
Jeżeli istnieje już gotowe i polecane rozwiązanie dotyczące bezpieczeństwa, użyj go. Najprawdopodobniej jest bardziej przemyślane, a także zostało sprawdzone wielokrotnie w boju.
Osobiście podjąłem się implementacji wyłącznie w celu edukacyjnym.
Każda implementacja różni się od siebie, poniżej przedstawiam prosty schemat z wykorzystaniem tokenów JWT.
Krótkie uzupełnienie niektórych kroków:
- System generuje jednorazowy token
Nie musi to być nic wymyślnego, sam używam do tego zwykłego UUID. Ważne, żeby nie dało się przewidzieć kolejnego tokenu oraz żeby był ograniczony czasowo. W mojej wersji do bazy oprócz samego tokenu zapisuję także timestamp zwiększony o 15 minut. Po tym czasie token zostaje unieważniony przy próbie zalogowania - System wysyła link z magic linkiem
Link powinien zawierać w sobie oczywiście wcześniej wygenerowany token jednorazowy i prowadzić na widok, który go zweryfikuje. Do wysyłania e-maili polecam usługę MailJet. Posiadają wygodne API, a pierwsze 300 wiadomości w miesiącu jest darmowe - System ustawia cookie HttpOnly z access tokenem
Oczywiście sam atrybut HttpOnly nie wystarczy, warto zaznajomić się także z pozostałymi właściwościami ciasteczek
Do takiego scenariusza bez problemu można wpiąć refresh token, tak aby nie nadawać zbyt długiego okresu życia access tokenowi.
Rejestracja użytkownika przebiega praktycznie identycznie. Jedyną różnicą jest to, że oprócz zapisania jednorazowego tokenu zapisujemy też do bazy nowego użytkownika. Cała reszta może przebiegać identycznie, w końcu samo zalogowanie będzie świadczyło o aktywacji konta.
Kiedy zastosować logowanie przez link?
Moim zdaniem najlepszym scenariuszem jest serwis, na który użytkownik wchodzi stosunkowo rzadko, ale wraca do niego co jakiś czas. Wtedy klikanie w link nie jest uciążliwe, a zaleta w postaci braku potrzeby pamiętania hasła faktycznie staje się czymś sensownym.
Gdybym miał zastosować logowanie przez link do serwisu, gdzie użytkownik pojawia się często, to koniecznie dodałbym do tego mechanizm “zapamiętaj mnie”. Dzięki temu ograniczmy konieczność wchodzenia na skrzynkę e‑mail. Tutaj dobrym pomysłem byłoby zastosowanie refresh tokena.
Zupełnie nietrafionym pomysłem będą serwisy przechowujące ważne dane (np. system bankowy). Pomijając już temat dwuetapowej weryfikacji, to takie systemy powinny być moim zdaniem pozbawione pośredników na etapie dostępu do konta.
Jest to pierwszy wpis do serii, którą opieram o doświadczenia, jakie zdobyłem podczas tworzenia swojego projektu GdzieIść. Zapraszam do odwiedzenia strony osoby lubiące chodzić po górach (i nie tylko), szczególnie jeżeli chcą podzielić się swoimi wycieczkami z innymi. Gwarantuję, że wasze hasła nie wyciekną ;)
Dzięki za przeczytanie wpisu i do kolejnego razu!
* ikonki używane w diagramach pochodzą z Icons8