Mit einem Passkey über die Funktion „Autofill“ anmelden

Erstellen Sie eine Anmeldung, bei der Passkeys verwendet werden, aber auch Nutzer mit vorhandenen Passwörtern berücksichtigt werden.

In diesem Leitfaden wird beschrieben, wie Sie die Funktion zum automatischen Ausfüllen von Formularen verwenden, damit sich Nutzer neben Passwörtern auch mit Passkeys anmelden können. Durch die automatische Vervollständigung von Formularen wird ein einheitlicher Anmeldeprozess geschaffen, der den Übergang von Passwörtern zur sichereren und nutzerfreundlicheren Passkey-Authentifizierungsmethode vereinfacht.

Hier erfahren Sie, wie Sie die bedingte Benutzeroberfläche von WebAuthn implementieren, um sowohl Nutzer mit Passkeys als auch Nutzer mit Passwörtern mit minimalen Reibungsverlusten in Ihren bestehenden Anmeldeformularen zu unterstützen.

Warum sollte ich die Autofill-Funktion für Formulare verwenden, um mich mit einem Passkey anzumelden?

Mit Passkeys können sich Nutzer mit ihrem Fingerabdruck, ihrem Gesicht oder der Geräte-PIN auf Websites anmelden.

Wenn alle Nutzer Passkeys hätten, könnte der Authentifizierungsablauf über eine Schaltfläche für die Einmalanmeldung erfolgen. Durch Tippen auf die Schaltfläche konnte der Nutzer das Konto direkt mit der Displaysperre bestätigen und sich anmelden.

Die Umstellung von Passwörtern auf Passkeys birgt jedoch auch Herausforderungen. Websites müssen in diesem Zeitraum sowohl Nutzer mit Passwörtern als auch Nutzer mit Passkeys unterstützen. Wenn Nutzer sich merken müssen, welche Websites Passkeys verwenden, und sie aufgefordert werden, vorab eine Anmeldemethode auszuwählen, ist das nicht nutzerfreundlich.

Passkeys sind auch eine neue Technologie und es kann schwierig sein, sie klar zu erklären. Die Verwendung der vertrauten Autofill-Oberfläche trägt sowohl zur Bewältigung der Umstellungsherausforderung als auch zur Nutzerfreundlichkeit bei.

Bedingte Benutzeroberfläche verwenden

Damit sowohl Nutzer mit Passkeys als auch Nutzer mit Passwörtern effektiv unterstützt werden, sollten Sie Passkeys in die Vorschläge zum automatischen Ausfüllen Ihres Formulars aufnehmen. Bei diesem Ansatz wird bedingte Benutzeroberfläche verwendet, eine Funktion des WebAuthn-Standards.

Beispiel für die Passkey-Auswahl über das automatische Ausfüllen von Formularen.

Wenn der Nutzer den Fokus auf das Eingabefeld für den Nutzernamen legt, wird ein Dialogfeld für das automatische Ausfüllen angezeigt, in dem gespeicherte Passkeys und Passwörter vorgeschlagen werden. Der Nutzer kann entweder einen Passkey oder ein Passwort auswählen und sich dann anmelden. Wenn er einen Passkey auswählt, wird die Displaysperre des Geräts verwendet.

So können sich Nutzer mit dem vorhandenen Anmeldeformular auf Ihrer Website anmelden, aber mit dem zusätzlichen Sicherheitsvorteil von Passkeys, falls sie einen haben.

So funktioniert die Passkey-Authentifizierung

Zur Authentifizierung mit einem Passkey verwenden Sie die WebAuthn API.

Die vier Komponenten eines Passkey-Authentifizierungsablaufs sind:

  • Backend: Hier werden Nutzerkontodetails gespeichert, einschließlich des öffentlichen Schlüssels.
  • Frontend: Kommuniziert mit dem Browser und ruft die erforderlichen Daten aus dem Backend ab.
  • Browser: Führt Ihr JavaScript aus und interagiert mit der WebAuthn API.
  • Passkey-Anbieter: Erstellt und speichert den Passkey. Das ist in der Regel ein Passwortmanager wie der Google Passwortmanager oder ein Sicherheitsschlüssel.
Ablauf der Passkey-Authentifizierung mit Interaktion zwischen Frontend, Backend, Browser und Passkey-Anbieter.
Vollständiger Ablauf der Passkey-Authentifizierung.

Der Prozess der Passkey-Authentifizierung läuft so ab:

  1. Der Nutzer ruft die Anmeldeseite auf und das Frontend fordert eine Authentifizierungs-Challenge vom Backend an.
  2. Das Backend generiert und gibt eine WebAuthn-Challenge zurück, die mit dem Konto des Nutzers verknüpft ist.
  3. Das Frontend ruft navigator.credentials.get() mit der Challenge auf, um die Authentifizierung über den Browser zu starten.
  4. Der Browser, der mit dem Passkeys-Anbieter interagiert, fordert den Nutzer auf, einen Passkey auszuwählen (oft über ein Autofill-Dialogfeld, das durch Fokussieren des Anmeldefelds ausgelöst wird) und seine Identität über die Gerätesperre oder biometrische Daten zu bestätigen.
  5. Nach erfolgreicher Nutzerüberprüfung signiert der Passkey-Anbieter die Challenge und der Browser gibt die resultierende Public-Key-Anmeldedaten (einschließlich der Signatur) an das Frontend zurück.
  6. Das Frontend sendet diese Anmeldedaten an das Backend.
  7. Das Backend vergleicht die Signatur des Anmeldedaten mit dem gespeicherten öffentlichen Schlüssel des Nutzers. Wenn die Überprüfung erfolgreich ist, meldet das Backend den Nutzer an.

Mit einem Passkey über das automatische Ausfüllen von Formularen authentifizieren

Um die Passkey-Authentifizierung mit Autofill für Formulare zu starten, führen Sie einen bedingten WebAuthn-get-Aufruf aus, wenn die Anmeldeseite geladen wird. Dieser Aufruf von navigator.credentials.get() enthält die Option mediation: 'conditional'.
Eine bedingte Anfrage an die WebAuthn-API navigator.credentials.get() zeigt nicht sofort die Benutzeroberfläche an. Stattdessen wird der Vorgang in einem ausstehenden Status fortgesetzt, bis der Nutzer mit dem Autofill-Prompt des Felds „Nutzername“ interagiert. Wenn der Nutzer einen Passkey auswählt, löst der Browser das ausstehende Promise mit einem Anmeldedatenobjekt auf, um den Nutzer anzumelden. Die herkömmliche Formularübermittlung wird dabei umgangen. Wenn der Nutzer stattdessen ein Passwort auswählt, wird das Promise nicht aufgelöst und der standardmäßige Passwortanmeldevorgang wird fortgesetzt. Die Seite ist dann dafür verantwortlich, den Nutzer anzumelden.

Formulareingabefeld annotieren

Wenn Sie die automatische Vervollständigung von Passkeys aktivieren möchten, fügen Sie dem Feld input für den Nutzernamen Ihres Formulars das Attribut autocomplete hinzu. Geben Sie sowohl username als auch webauthn als durch Leerzeichen getrennte Werte an.

<input type="text" name="username" autocomplete="username webauthn" autofocus>

Wenn Sie diesem Feld autofocus hinzufügen, wird beim Laden der Seite automatisch die Aufforderung zum automatischen Ausfüllen ausgelöst und verfügbare Passwörter und Passkeys werden sofort angezeigt.

Funktionserkennung

Prüfen Sie vor dem Aufrufen eines bedingten WebAuthn-API-Aufrufs, ob Folgendes zutrifft:

  • Der Browser unterstützt WebAuthn mit PublicKeyCredential.

Browser Support

  • Chrome: 67.
  • Edge: 18.
  • Firefox: 60.
  • Safari: 13.

Source

  • Der Browser unterstützt die Erkennung von Funktionen mit PublicKeyCredential.getClientCapabilities().

Browser Support

  • Chrome: 133.
  • Edge: 133.
  • Firefox: 135.
  • Safari: 17.4.

Source

Das folgende Snippet zeigt, wie Sie prüfen können, ob der Browser diese Funktionen unterstützt:

if (window.PublicKeyCredential && PublicKeyCredential.getClientCapabilities) {
  const capabilities = await PublicKeyCredential.getClientCapabilities();
  // Check if conditional mediation is available.  
  if (capabilities.conditionalGet === true) {
    // The browser supports conditional mediation.
  }
}

Informationen aus dem Backend abrufen

Ihr Backend muss dem Frontend mehrere Optionen zum Initiieren des navigator.credentials.get()-Aufrufs zur Verfügung stellen. Diese Optionen werden in der Regel als JSON-Objekt von einem Endpunkt auf Ihrem Server abgerufen.

Zu den wichtigsten Eigenschaften im Optionen-Objekt gehören:

  • challenge: Eine vom Server generierte Challenge in einem ArrayBuffer (in der Regel Base64URL-codiert für den JSON-Transport). Dies ist wichtig, um Wiederholungsversuche zu verhindern. Ihr Server muss für jeden Anmeldeversuch eine neue Challenge generieren und sie nach kurzer Zeit oder bei einem fehlgeschlagenen Versuch ungültig machen.
  • allowCredentials: Ein Array von Anmeldedaten-Deskriptoren. Übergeben Sie ein leeres Array. Dadurch wird der Browser aufgefordert, alle Anmeldedaten für die angegebene rpId aufzulisten.
  • userVerification: Gibt Ihre bevorzugte Methode zur Nutzerbestätigung an, z. B. die Anforderung einer Displaysperre für das Gerät. Der Standardwert und der empfohlene Wert ist "preferred". Mögliche Werte:

    • "required": Die Nutzerbestätigung muss vom Authentifikator (z. B. PIN oder biometrisches Verfahren) durchgeführt werden. Der Vorgang schlägt fehl, wenn die Bestätigung nicht durchgeführt werden kann.
    • "preferred": Der Authentifikator versucht, den Nutzer zu bestätigen, aber der Vorgang kann auch ohne Bestätigung erfolgreich sein.
    • "discouraged": Der Authentifikator sollte die Nutzerüberprüfung nach Möglichkeit vermeiden.
  • rpId: Ihre Relying Party-ID, in der Regel die Domain Ihrer Website (z. B. example.com). Dieser Wert muss genau mit dem rp.id übereinstimmen, das beim Erstellen der Passkey-Anmeldedaten verwendet wurde.

Ihr Server sollte dieses Optionenobjekt erstellen. ArrayBuffer-Werte (wie challenge) müssen für den JSON-Transport Base64URL-codiert sein. Verwenden Sie im Frontend nach dem Parsen des JSON PublicKeyCredential.parseRequestOptionsFromJSON(), um das Objekt (einschließlich der Decodierung von Base64URL-Strings) in das Format zu konvertieren, das navigator.credentials.get() erwartet.

Das folgende Code-Snippet zeigt, wie Sie die Informationen abrufen und decodieren können, die für die Authentifizierung mit einem Passkey erforderlich sind.

// Fetch an encoded PubicKeyCredentialRequestOptions from the server.
const _options = await fetch('/webauthn/signinRequest');

// Deserialize and decode the PublicKeyCredentialRequestOptions.
const decoded_options = JSON.parse(_options);
const options = PublicKeyCredential.parseRequestOptionsFromJSON(decoded_options);
...

WebAuthn API mit dem Flag conditional aufrufen, um den Nutzer zu authentifizieren

Sobald Sie das publicKeyCredentialRequestOptions-Objekt (im Beispielcode unten als options bezeichnet) vorbereitet haben, rufen Sie navigator.credentials.get() auf, um die bedingte Passkey-Authentifizierung zu starten.

// To abort a WebAuthn call, instantiate an AbortController.
const abortController = new AbortController();

// Invoke WebAuthn to authenticate with a passkey.
const credential = await navigator.credentials.get({
  publicKey: options,
  signal: abortController.signal,
  // Specify 'conditional' to activate conditional UI
  mediation: 'conditional'
});

Wichtige Parameter für diesen Aufruf:

  • publicKey: Dies muss das publicKeyCredentialRequestOptions-Objekt (im Beispiel options genannt) sein, das Sie im vorherigen Schritt von Ihrem Server abgerufen und verarbeitet haben.
  • signal: Wenn Sie das Signal eines AbortController (z. B. abortController.signal) übergeben, können Sie die get()-Anfrage programmatisch abbrechen. Das ist nützlich, wenn Sie einen anderen WebAuthn-Aufruf aufrufen möchten.
  • mediation: 'conditional': Dies ist das entscheidende Flag, das den WebAuthn-Aufruf bedingt macht. Dadurch wird der Browser angewiesen, auf die Interaktion des Nutzers mit einer Aufforderung zur automatischen Vervollständigung zu warten, anstatt sofort ein modales Dialogfeld anzuzeigen.

Zurückgegebenes Public-Key-Credential an den RP-Server senden

Wenn der Nutzer einen Passkey auswählt und seine Identität erfolgreich bestätigt (z. B. mit der Displaysperre seines Geräts), wird das navigator.credentials.get()-Promise aufgelöst. Dadurch wird ein PublicKeyCredential-Objekt an Ihr Frontend zurückgegeben.

Das Promise kann aus verschiedenen Gründen abgelehnt werden. Sie sollten diese Fehler in Ihrem Code verarbeiten, indem Sie die name-Eigenschaft des Error-Objekts prüfen:

  • NotAllowedError: Der Nutzer hat den Vorgang abgebrochen oder es wurde kein Passkey ausgewählt.
  • AbortError: Der Vorgang wurde abgebrochen, möglicherweise durch Ihren Code mit einem AbortController.
  • Andere Ausnahmen: Ein unerwarteter Fehler ist aufgetreten. Der Browser zeigt dem Nutzer in der Regel ein Fehlerdialogfeld an.

Das PublicKeyCredential-Objekt enthält mehrere Attribute. Zu den wichtigsten Eigenschaften, die für die Authentifizierung relevant sind, gehören:

  • id: Die base64url-codierte ID der authentifizierten Passkey-Anmeldedaten.
  • rawId: Eine ArrayBuffer-Version der Anmeldedaten-ID.
  • response.clientDataJSON: Ein ArrayBuffer mit Clientdaten. Dieses Feld enthält Informationen wie die Challenge und den Ursprung, die Ihr Server bestätigen muss.
  • response.authenticatorData: Ein ArrayBuffer mit Authentifikatordaten. Dieses Feld enthält Informationen wie die RP‑ID.
  • response.signature: Ein ArrayBuffer mit der Signatur. Dieser Wert ist der Kern der Anmeldedaten und Ihr Server muss diese Signatur mit dem gespeicherten öffentlichen Schlüssel für die Anmeldedaten überprüfen .
  • response.userHandle: Ein ArrayBuffer, der die bei der Passkey-Registrierung angegebene Nutzer-ID enthält.
  • authenticatorAttachment: Gibt an, ob der Authentifikator Teil des Clientgeräts (platform) oder extern (cross-platform) ist. Eine cross-platform-Anhängung kann auftreten, wenn der Nutzer sich mit einem Smartphone angemeldet hat. In solchen Fällen können Sie den Nutzer auffordern, einen Passkey auf dem aktuellen Gerät zu erstellen, um sich in Zukunft einfacher anmelden zu können.
  • type: Dieses Feld ist immer auf "public-key" gesetzt.

Wenn Sie dieses PublicKeyCredential-Objekt an Ihr Backend senden möchten, rufen Sie zuerst die Methode .toJSON() auf. Mit dieser Methode wird eine JSON-serialisierbare Version des Anmeldedatenobjekts erstellt, in der die Konvertierung von ArrayBuffer-Eigenschaften (z. B. rawId, clientDataJSON, authenticatorData, signature und userHandle) in Base64URL-codierte Strings korrekt verarbeitet wird. Verwenden Sie dann JSON.stringify(), um dieses Objekt in einen String umzuwandeln und im Text Ihrer Anfrage an den Server zu senden.

...
// Encode and serialize the PublicKeyCredential.
const _result = credential.toJSON();
const result = JSON.stringify(_result);

// Encode and send the credential to the server for verification.  
const response = await fetch('/webauthn/signinResponse', {
  method: 'post',
  credentials: 'same-origin',
  body: result
});

Überprüfen Sie die Signatur

Wenn Ihr Backend-Server die Anmeldedaten für den öffentlichen Schlüssel empfängt, muss er ihre Authentizität überprüfen. Das umfasst:

  1. Anmeldedaten parsen
  2. Der gespeicherte öffentliche Schlüssel, der mit der id des Anmeldedaten verknüpft ist, wird gesucht.
  3. Die empfangene signature wird anhand des gespeicherten öffentlichen Schlüssels geprüft.
  4. Andere Daten wie die Challenge und die Herkunft werden validiert.

Wir empfehlen, eine serverseitige FIDO-/WebAuthn-Bibliothek zu verwenden, um diese kryptografischen Vorgänge sicher auszuführen. Open-Source-Bibliotheken finden Sie im GitHub-Repository „awesome-webauthn“.

Wenn die Signatur und alle anderen Zusicherungen gültig sind, kann der Server den Nutzer anmelden. Ausführliche Schritte zur serverseitigen Validierung finden Sie unter Serverseitige Passkey-Authentifizierung.

Signal, wenn die entsprechenden Anmeldedaten im Backend nicht gefunden werden

Wenn Ihr Backend-Server bei der Anmeldung keine Anmeldedaten mit einer übereinstimmenden ID findet, hat der Nutzer diesen Passkey möglicherweise zuvor von Ihrem Server, aber nicht von seinem Passkey-Anbieter gelöscht. Diese Diskrepanz kann zu einer verwirrenden Nutzererfahrung führen, wenn der Passkey-Anbieter weiterhin einen Passkey vorschlägt, der nicht mehr mit Ihrer Website funktioniert. Um dies zu verbessern, sollten Sie den Passkey-Anbieter auffordern, den verwaisten Passkey zu entfernen.

Mit der Methode PublicKeyCredential.signalUnknownCredential(), die Teil der Webauthn Signal API ist, können Sie den Passkey-Anbieter darüber informieren, dass die angegebene Anmeldedaten entfernt wurden oder nicht vorhanden sind. Rufen Sie diese statische Methode auf der Clientseite auf, wenn Ihr Server angibt (z. B. mit einem bestimmten HTTP-Statuscode wie 404), dass eine angegebene Anmeldedaten-ID unbekannt ist. Stellen Sie dieser Methode die RP‑ID und die ID der unbekannten Anmeldedaten zur Verfügung. Der Passkey-Anbieter sollte den Passkey entfernen, wenn er das Signal unterstützt.

// Detect authentication failure due to lack of the credential
if (response.status === 404) {
  // Feature detection
  if (PublicKeyCredential.signalUnknownCredential) {
    await PublicKeyCredential.signalUnknownCredential({
      rpId: "example.com",
      credentialId: "vI0qOggiE3OT01ZRWBYz5l4MEgU0c7PmAA" // base64url encoded credential ID
    });
  } else {
    // Encourage the user to delete the passkey from the password manager nevertheless.
    ...
  }
}

Nach der Authentifizierung

Je nachdem, wie sich der Nutzer angemeldet hat, schlagen wir verschiedene Abläufe vor.

Wenn sich der Nutzer ohne Passkey angemeldet hat

Wenn sich der Nutzer ohne Passkey auf Ihrer Website angemeldet hat, ist möglicherweise kein Passkey für dieses Konto oder auf seinem aktuellen Gerät registriert. Dies ist ein guter Zeitpunkt, um Nutzer dazu zu ermutigen, Passkeys zu erstellen. Hier einige Beispiele:

  • Passwörter auf Passkeys umstellen: Verwenden Sie conditional create, eine WebAuthn-Funktion, mit der der Browser nach einer erfolgreichen Anmeldung mit Passwort automatisch einen Passkey für den Nutzer erstellen kann. Dies kann die Einführung von Passkeys erheblich verbessern, da der Erstellungsprozess vereinfacht wird. Weitere Informationen
  • Manuell zur Passkey-Erstellung auffordern: Nutzer dazu auffordern, einen Passkey zu erstellen. Dies kann effektiv sein, nachdem ein Nutzer einen aufwendigeren Anmeldevorgang durchlaufen hat, z. B. die Multi-Faktor-Authentifizierung (MFA). Vermeiden Sie jedoch zu viele Aufforderungen, da diese die Nutzerfreundlichkeit beeinträchtigen können.“

Beispiele dafür, wie Sie Nutzer dazu anregen können, einen Passkey zu erstellen, und weitere Best Practices finden Sie unter Passkeys für Nutzer kommunizieren.

Wenn sich der Nutzer mit einem Passkey angemeldet hat

Nachdem sich ein Nutzer erfolgreich mit einem Passkey angemeldet hat, haben Sie mehrere Möglichkeiten, die Nutzerfreundlichkeit zu verbessern und die Kontokonsistenz aufrechtzuerhalten.

Nach einer geräteübergreifenden Authentifizierung zum Erstellen eines neuen Passkeys auffordern

Wenn sich ein Nutzer mit einem Passkey über einen geräteübergreifenden Mechanismus anmeldet (z. B. durch Scannen eines QR-Codes mit seinem Smartphone), wird der verwendete Passkey möglicherweise nicht lokal auf dem Gerät gespeichert, auf dem er sich anmeldet. Dies kann in folgenden Fällen passieren:

  • Sie haben einen Passkey, aber bei einem Passkey-Anbieter, der das Betriebssystem oder den Browser für die Anmeldung nicht unterstützt.
  • Sie haben den Zugriff auf den Passkey-Anbieter auf dem Gerät verloren, auf dem sie sich anmelden, aber ein Passkey ist auf einem anderen Gerät verfügbar.

In diesem Fall sollten Sie den Nutzer auffordern, einen neuen Passkey auf dem aktuellen Gerät zu erstellen. So müssen sie sich in Zukunft nicht noch einmal auf mehreren Geräten anmelden. Wenn Sie feststellen möchten, ob sich der Nutzer mit einem geräteübergreifenden Passkey angemeldet hat, prüfen Sie die authenticatorAttachment-Property der Anmeldedaten. Wenn der Wert "cross-platform" ist, weist das auf eine geräteübergreifende Authentifizierung hin. Wenn ja, erkläre ihm, wie einfach es ist, einen neuen Passkey zu erstellen, und führe ihn durch den Erstellungsprozess.

Passkey-Details mithilfe von Signalen mit dem Anbieter synchronisieren

Um für Konsistenz und eine bessere Nutzerfreundlichkeit zu sorgen, kann Ihre vertrauende Partei (Relying Party, RP) die WebAuthn Signals API verwenden, um Aktualisierungen von Anmeldedaten und Nutzerinformationen an den Passkey-Anbieter zu senden.

Damit die Liste der Passkeys eines Nutzers beim Passkey-Anbieter immer aktuell ist, müssen die Anmeldedaten im Backend synchronisiert werden. Sie können angeben, dass ein Passkey nicht mehr vorhanden ist, damit die Passkey-Anbieter unnötige Passkeys entfernen können.

Ebenso können Sie signalisieren, wenn ein Nutzer seinen Nutzernamen oder Anzeigenamen in Ihrem Dienst aktualisiert, damit die vom Passkey-Anbieter angezeigten Nutzerinformationen (z. B. in Dialogfeldern zur Kontoauswahl) auf dem neuesten Stand bleiben.

Weitere Informationen zu Best Practices für die Konsistenz von Passkeys finden Sie unter Passkeys mit der Signal API mit Anmeldedaten auf Ihrem Server konsistent halten.

Keinen zweiten Faktor anfordern

Passkeys bieten einen umfassenden, integrierten Schutz vor gängigen Bedrohungen wie Phishing. Ein zweiter Authentifizierungsfaktor bietet daher keinen wesentlichen zusätzlichen Sicherheitswert. Stattdessen wird ein unnötiger Schritt für Nutzer bei der Anmeldung erstellt.

Checkliste

  • Nutzern erlauben, sich mit einem Passkey über das automatische Ausfüllen von Formularen anzumelden
  • Signalisiert, wenn die entsprechenden Anmeldedaten für einen Passkey nicht im Backend gefunden werden.
  • Nutzer auffordern, manuell einen Passkey zu erstellen, wenn sie nach der Anmeldung noch keinen erstellt haben.
  • Einen Passkey automatisch erstellen (bedingte Erstellung), nachdem sich der Nutzer mit einem Passwort (und einem zweiten Faktor) angemeldet hat.
  • Aufforderung zur Erstellung eines lokalen Passkeys, wenn sich der Nutzer mit einem geräteübergreifenden Passkey angemeldet hat.
  • Signalisiere dem Anbieter nach der Anmeldung oder bei Änderungen die Liste der verfügbaren Passkeys und die aktualisierten Nutzerdetails (Nutzername, Anzeigename).

Ressourcen