Utwórz sposób logowania, który korzysta z kluczy dostępu, a jednocześnie umożliwia obsługę obecnych haseł.
Klucze dostępu zastępują hasła i sprawiają, że konta użytkowników w internecie są bezpieczniejsze, prostsze i łatwiejsze w obsłudze. Jednak przejście z uwierzytelniania opartego na haśle na klucz dostępu może skomplikować wrażenia użytkowników. Używanie autouzupełniania formularzy do sugerowania kluczy dostępu może pomóc w stworzeniu ujednoliconego procesu.
Dlaczego do logowania się za pomocą klucza dostępu warto używać autouzupełniania formularzy?
Dzięki kluczowi dostępu użytkownik może logować się w witrynie przy użyciu odcisku palca, wizerunku twarzy lub kodu PIN urządzenia.
W idealnej sytuacji nie powinno być użytkowników, którzy podają hasło, a proces uwierzytelniania mógłby być tak prosty, jak za pomocą jednego przycisku logowania. Po jego kliknięciu pojawia się okno wyboru konta, w którym użytkownik może wybrać konto, odblokować ekran, aby przejść weryfikację i się zalogować.
Jednak przejście z uwierzytelniania na hasło na podstawie klucza dostępu może być trudne. Gdy użytkownicy przechodzą na klucze dostępu, niektórzy użytkownicy korzystający z haseł i witryny będą musieli obsługiwać oba te typy użytkowników. Użytkownicy nie powinni zapamiętywać, z których witryn przenieśli się na klucze dostępu, więc proszenie ich o wybranie metody z góry nie zapewni użytkownikom dobrych wrażeń.
Klucze dostępu to również nowa technologia. Wyjaśnienie tych kwestii i dbanie o to, by użytkownicy są mogli z nich wygodnie korzystać, może być wyzwaniem dla witryn. Aby rozwiązać oba problemy, w przypadku autouzupełniania haseł możemy polegać na znanych interfejsach użytkownika.
Interfejs warunkowy
Aby zwiększyć wygodę użytkowników korzystających zarówno z kluczy dostępu, jak i haseł, możesz uwzględniać klucze dostępu w sugestiach autouzupełniania. Nazywa się to warunkowym interfejsem użytkownika i jest częścią standardu WebAuthn.
Gdy tylko użytkownik kliknie pole do wpisania nazwy użytkownika, pojawi się okno z sugestią autouzupełniania, w której wyróżnione będą zapisane klucze dostępu wraz z sugestiami autouzupełniania haseł. Następnie użytkownik może wybrać konto i używać blokady ekranu urządzenia, aby się zalogować.
W ten sposób użytkownicy będą mogli logować się w Twojej witrynie przy użyciu dotychczasowego formularza, tak jakby nic się nie zmieniło. Będzie to jednak miało dodatkowe korzyści w związku z bezpieczeństwem kluczy dostępu (jeśli go ma).
Jak to działa
Do uwierzytelniania za pomocą klucza dostępu służy interfejs WebAuthn API.
4 elementy uwierzytelniania za pomocą klucza dostępu to: użytkownik:
- Backend: serwer backendu, w którym znajduje się baza danych kont przechowująca klucz publiczny i inne metadane klucza dostępu.
- Frontend: frontend, który komunikuje się z przeglądarką i wysyła żądania pobierania do backendu.
- Przeglądarka: przeglądarka użytkownika, która używa Twojego JavaScriptu.
- Authenticator: mechanizm uwierzytelniający użytkownika, który tworzy i przechowuje klucz dostępu. Może być na tym samym urządzeniu co przeglądarka (np.w Windows Hello) lub na innym urządzeniu, np. telefonie.
- Gdy tylko użytkownik trafia do frontendu, wysyła od backendu żądanie uwierzytelnienia za pomocą klucza dostępu i wywołuje
navigator.credentials.get()
w celu zainicjowania uwierzytelniania za pomocą klucza dostępu. Zwraca wartośćPromise
. - Gdy użytkownik umieści kursor w polu logowania, przeglądarka wyświetli okno autouzupełniania hasła z kluczami dostępu. Jeśli użytkownik wybierze klucz dostępu, pojawi się okno uwierzytelniania.
- Gdy użytkownik potwierdzi swoją tożsamość przy użyciu blokady ekranu urządzenia, obietnica zostanie zrealizowana, a dane uwierzytelniające klucza publicznego zostaną zwrócone do frontendu.
- Frontend wysyła do backendu dane uwierzytelniające klucza publicznego. Backend weryfikuje podpis pod kątem klucza publicznego dopasowanego konta w bazie danych. Jeśli próba się powiedzie, użytkownik będzie zalogowany.
Wymagania wstępne
Warunkowy interfejs WebAuthn jest publicznie obsługiwany w Safari na urządzeniach z iOS 16, iPadOS 16 i macOS Ventura. Jest też dostępna w Chrome na urządzeniach z Androidem, macOS i Windows 11 (22H2).
Uwierzytelniaj za pomocą klucza dostępu przez autouzupełnianie formularzy
Gdy użytkownik chce się zalogować, możesz wykonać warunkowe wywołanie get
WebAuthn, aby wskazać, że w sugestiach autouzupełniania mogą być uwzględniane klucze dostępu. Warunkowe wywołanie interfejsu API navigator.credentials.get()
usługi WebAuthn nie wyświetla interfejsu użytkownika i pozostaje oczekujące, dopóki z sugestii autouzupełniania użytkownik nie wybierze konta, na które ma się zalogować. Jeśli użytkownik wybierze klucz dostępu, przeglądarka rozstrzygnie obietnicę za pomocą danych logowania, a nie formularza logowania. Obowiązek zalogowania się
na stronie spoczywa na stronie.
Pole do wprowadzania adnotacji w formularzu
W razie potrzeby dodaj atrybut autocomplete
do pola nazwy użytkownika input
.
Dołącz username
i webauthn
jako jego tokeny, aby umożliwić sugerowanie kluczy dostępu.
<input type="text" name="username" autocomplete="username webauthn" ...>
Wykrywanie funkcji
Przed wywołaniem warunkowego wywołania interfejsu WebAuthn API sprawdź, czy:
- Przeglądarka obsługuje WebAuthn.
- Przeglądarka obsługuje interfejs warunkowy WebAuthn.
// Availability of `window.PublicKeyCredential` means WebAuthn is usable.
if (window.PublicKeyCredential &&
PublicKeyCredential.isConditionalMediationAvailable) {
// Check if conditional mediation is available.
const isCMA = await PublicKeyCredential.isConditionalMediationAvailable();
if (isCMA) {
// Call WebAuthn authentication
}
}
Pobierz wyzwanie z serwera RP
Pobierz z serwera RP wyzwanie, które jest wymagane do wywołania
navigator.credentials.get()
:
challenge
: wyzwanie wygenerowane przez serwer w Buforze tablicy. Jest to konieczne, aby zapobiegać atakom metodą powtórzenia. Pamiętaj, aby generować nowe wyzwanie przy każdej próbie logowania i zignorować je po określonym czasie lub wtedy, gdy próba logowania się nie powiedzie. Traktuj go jak token CSRF.allowCredentials
: tablica akceptowanych danych uwierzytelniających podczas tego uwierzytelniania. Przekaż pustą tablicę, aby umożliwić użytkownikowi wybranie dostępnego klucza z listy wyświetlanej przez przeglądarkę.userVerification
: Wskazuje, czy weryfikacja użytkownika przy użyciu blokady ekranu urządzenia to"required"
,"preferred"
czy"discouraged"
. Wartość domyślna to"preferred"
, co oznacza, że mechanizm uwierzytelniania może pominąć weryfikację użytkownika. Ustaw tę wartość na"preferred"
lub pomiń tę właściwość.
Wywołaj interfejs WebAuthn API z flagą conditional
, aby uwierzytelnić użytkownika
Wywołaj navigator.credentials.get()
, aby rozpocząć oczekiwanie na uwierzytelnienie użytkownika.
// To abort a WebAuthn call, instantiate an `AbortController`.
const abortController = new AbortController();
const publicKeyCredentialRequestOptions = {
// Server generated challenge
challenge: ****,
// The same RP ID as used during registration
rpId: 'example.com',
};
const credential = await navigator.credentials.get({
publicKey: publicKeyCredentialRequestOptions,
signal: abortController.signal,
// Specify 'conditional' to activate conditional UI
mediation: 'conditional'
});
rpId
: Identyfikator RP to domena, a witryna może określać swoją domenę lub sufiks dostępny do zarejestrowania. Ta wartość musi być zgodna z identyfikatorem rp.id użytym podczas tworzenia klucza dostępu.
Pamiętaj, by określić właściwość mediation: 'conditional'
, by żądanie było warunkowe.
Wyślij zwrócone dane uwierzytelniające klucza publicznego do serwera RP
Gdy użytkownik wybierze konto i wyrazi zgodę przy użyciu blokady ekranu urządzenia, obietnica zostanie zrealizowana, a obiekt PublicKeyCredential
zostanie zwrócony do frontendu RP.
Obietnica może zostać odrzucona z kilku różnych powodów. Musisz naprawić błędy w zależności od właściwości name
obiektu Error
:
NotAllowedError
: użytkownik anulował operację.- Inne wyjątki: wystąpiło coś nieoczekiwanego. Przeglądarka wyświetli użytkownikowi okno z błędem.
Obiekt danych logowania klucza publicznego zawiera te właściwości:
id
: zakodowany w base64url identyfikator uwierzytelnionych danych logowania klucza dostępu.rawId
: wersja identyfikatora danych logowania w formacie ArrayBuffer.response.clientDataJSON
: obiekt ArrayBuffer z danymi klienta. Zawiera ono informacje takie jak test zabezpieczający oraz źródło, które musi zweryfikować serwer RP.response.authenticatorData
: obiekt ArrayBuffer z danymi uwierzytelniającymi. To pole zawiera informacje, np. identyfikator RP.response.signature
: tablica Buffer podpisu. Ta wartość jest podstawą danych logowania i musi zostać zweryfikowana na serwerze.response.userHandle
: obiekt tablica Buffer zawierający identyfikator użytkownika ustawiony w czasie tworzenia. Tej wartości można użyć zamiast identyfikatora danych logowania, jeśli serwer musi wybrać używane wartości identyfikatora lub jeśli backend nie chce tworzyć indeksu dla identyfikatorów danych logowania.authenticatorAttachment
: Zwraca wartośćplatform
, gdy te dane logowania pochodzą z urządzenia lokalnego. W przeciwnym raziecross-platform
, zwłaszcza gdy użytkownik logował się przy użyciu telefonu. Jeśli użytkownik musi logować się przy użyciu telefonu, możesz poprosić go o utworzenie klucza dostępu na urządzeniu lokalnym.type
: to pole ma zawsze wartość"public-key"
.
Jeśli do obsługi obiektu danych logowania klucza publicznego na serwerze RP używasz biblioteki, zalecamy wysłanie całego obiektu na serwer po jego częściowym zakodowaniu w base64url.
Sprawdzanie podpisu
Gdy otrzymasz na serwerze dane uwierzytelniające klucza publicznego, przekaż je do biblioteki FIDO w celu przetworzenia obiektu.
Wyszukaj zgodny identyfikator danych logowania za pomocą właściwości id
(jeśli chcesz określić konto użytkownika, użyj właściwości userHandle
, której wartość user.id
została podana podczas tworzenia danych logowania). Sprawdź, czy signature
danych logowania można zweryfikować za pomocą zapisanego klucza publicznego. Zalecamy skorzystanie z biblioteki po stronie serwera lub innego rozwiązania zamiast pisania własnego kodu. Biblioteki open source znajdziesz w repozytorium Awesome-webauth na GitHubie.
Gdy dane logowania zostaną zweryfikowane przy użyciu pasującego klucza publicznego, zaloguj użytkownika.