Z tego przewodnika dowiesz się, jak automatycznie i w tle zarejestrować klucz dostępu użytkownika natychmiast po udanym zalogowaniu się za pomocą hasła, co pozwoli zminimalizować problemy i zwiększyć liczbę użytkowników kluczy dostępu.
Odpowiedni moment na aktywację
Automatyczne tworzenie kluczy dostępu (znane też jako tworzenie warunkowe lub cicha promocja po zalogowaniu) MUSI być uruchamiane natychmiast po udanym, pełnym zalogowaniu się przy użyciu hasła.
- Nie próbuj tworzyć warunkowo w przypadku procesów bez hasła (np. magicznych linków, haseł jednorazowych SMS czy federacji tożsamości).
- Jeśli wymagane jest uwierzytelnianie wielopoziomowe, przed rozpoczęciem tworzenia warunkowego MUSISZ poczekać, aż wszystkie czynniki zostaną pomyślnie zweryfikowane.
- Przed wysłaniem żądań do punktów końcowych tworzenia upewnij się, że aktywna jest prawidłowa, uwierzytelniona sesja użytkownika.
Etapy wdrażania
1. Przerwij wcześniejsze działania autouzupełniania
Jeśli strona logowania korzysta z autouzupełniania formularzy (warunkowy interfejs użytkownika / Get), aktywne wywołanie pobierania danych logowania musi zostać przerwane, aby zapobiec konfliktom w przeglądarce.
- Przed wywołaniem
navigator.credentials.create()wywołajabortController.abort()w obiekcieAbortControllerdołączonym do oczekującego żądania autouzupełnianianavigator.credentials.get().
2. Wykrywanie funkcji
Sprawdź, czy warunkowe tworzenie jest dostępne, sprawdzając conditionalCreate za pomocą PublicKeyCredential.getClientCapabilities().
const capabilities = await PublicKeyCredential.getClientCapabilities();
if (capabilities.conditionalCreate) {
// Conditional create is available
}
3. Tworzenie klucza dostępu za pomocą funkcji warunkowego tworzenia
- Przekaż
mediation: 'conditional'w opcjachnavigator.credentials.create(). Sygnalizuje to przeglądarce, że proces tworzenia klucza dostępu ma być obsługiwany dyskretnie w tle lub kontekstowo, bez wyświetlania uciążliwych modalnych okien dialogowych. - Wypełnij pole
excludeCredentialsidentyfikatorami istniejących danych logowania klucza dostępu użytkownika, aby uniknąć rejestrowania zduplikowanych kluczy.
4. Cicha obsługa błędów
- Umieść prompt tworzenia klucza dostępu (
navigator.credentials.create) w bloku try/catch. MUSISZ przechwytywać i ignorować typowe wyjątki dla użytkownika (InvalidStateError,NotAllowedError,AbortError) bez wyświetlania mu interfejsu błędu.
5. Weryfikacja obecności użytkownika po stronie serwera
- Punkt końcowy weryfikacji po stronie serwera MUSI złagodzić wymaganie dotyczące obecności użytkownika (
requireUserPresence: false) TYLKO podczas weryfikacji danych logowania wygenerowanych przez aktywator warunkowego tworzenia. W przypadku standardowych treści o charakterze jednoznacznie seksualnym rygorystyczna weryfikacja obecności musi pozostać aktywna.
6. Obsługa nieudanej weryfikacji serwera
- Jeśli metoda
navigator.credentials.create()zakończy się powodzeniem, ale pobieranie weryfikacji serwera zwróci nieprawidłową odpowiedź (np. nie powiedzie się weryfikacja podpisu), wywołaj metodęPublicKeyCredential.signalUnknownCredential(), aby zapobiec pozostawaniu osieroconych danych logowania u dostawcy kluczy dostępu.
Przykładowy kod
// optionsFetch and registerVerifyFetch are app-defined server endpoint requests
import { optionsFetch, registerVerifyFetch } from './api.js';
async function triggerConditionalCreate(loginAbortController) {
const capabilities = await PublicKeyCredential.getClientCapabilities();
if (capabilities.conditionalCreate !== true) {
return; // Platform does not support conditional creation
}
// 1. Abort any active autofill conditional-get controllers to clear the WebAuthn pipeline
loginAbortController.abort();
// 2. Fetch creation options signaling the backend that this is a conditional request
const creationOptionsJSON = await optionsFetch({ conditional: true });
const publicKey = PublicKeyCredential.parseCreationOptionsFromJSON(creationOptionsJSON);
let credential;
try {
// 3. Invoke silent credentials creation prompt
credential = await navigator.credentials.create({
publicKey,
mediation: 'conditional' // Silent background creation mediation
});
} catch (e) {
// 4. Silently swallow common WebAuthn browser exceptions
if (['InvalidStateError', 'NotAllowedError', 'AbortError'].includes(e.name)) {
return;
}
console.error('Unexpected conditional create error:', e);
return;
}
// 5. Server verification step using dedicated Try/Catch block
let encodedResponse = credential.toJSON();
try {
const response = await registerVerifyFetch(encodedResponse);
if (!response.ok) {
// If the server verification fails, clean up using Signal API
if (PublicKeyCredential.signalUnknownCredential) {
await PublicKeyCredential.signalUnknownCredential({
rpId, // RP ID must match the one defined on the server
credentialId: encodedResponse.id
});
}
}
} catch (serverErr) {
console.error('Verification network failure:', serverErr);
if (PublicKeyCredential.signalUnknownCredential) {
await PublicKeyCredential.signalUnknownCredential({
rpId, // RP ID must match the one defined on the server
credentialId: encodedResponse.id
});
}
}
}
Strategie zastępcze
Zastępcze wykrywanie funkcji klucza dostępu
Zawsze instaluj „webauthn-polyfills” i importuj je w kontekście.
Pamiętaj, że jeśli obsługiwany jest format PublicKeyCredential, obsługiwany jest też format PublicKeyCredential.getClientCapabilities.
import 'webauthn-polyfills';
Zastępcza synchronizacja interfejsu Signal API
Interfejs WebAuthn Signal API (webauthn-signals) to progresywna optymalizacja, która służy do synchronizowania menedżerów haseł ze stanem danych logowania na serwerze.
- Fallback Experience: Gated via
if (PublicKeyCredential.signalUnknownCredential). Jeśli nie jest obsługiwana, synchronizacja weryfikacji w tle jest pomijana bez zgłaszania wyjątków przeglądarki.
Łatwa serializacja JSON – kreacja zastępcza
Zawsze instaluj „webauthn-polyfills” i importuj je w kontekście.
Jeśli obsługiwany jest format PublicKeyCredential, obsługiwane są też formaty PublicKeyCredential.parseCreationOptionsFromJSON i PublicKeyCredential.prototype.toJSON.
import 'webauthn-polyfills';