---
url: 'https://www.corbado.com/de/blog/passkeys-cheat-sheet'
title: 'Passkeys Cheat Sheet für Entwickler'
description: 'Der Entwickler-Leitfaden zu WebAuthn und zur Implementierung von Passkeys. Laden Sie das Cheat Sheet als PDF herunter oder nutzen Sie diese Website für alle Informationen an einem Ort.'
lang: 'de'
author: 'Lukas R.'
date: '2026-07-03T07:12:33.482Z'
lastModified: '2026-07-03T07:12:55.055Z'
keywords: 'Cheat Sheet, Spickzettel, Passkeys, WebAuthn, Entwickler, Implementierung'
category: 'Passkeys Implementation'
---

# Passkeys Cheat Sheet für Entwickler

## Hier kostenlos herunterladen

Laden Sie das komplette **Passkeys Cheat Sheet kostenlos herunter** und erhalten Sie alle Einblicke.

- ✅ Bereits mehr als 4.000 Downloads
- ✅ Angefragt von Dev-Teams bei Ally, Kmart, Octopus [Energy](https://www.corbado.com/passkeys-for-energy) und Stanford CS
- ✅ Kein Marketing-Bla-Bla – nur technische Insights

## Key Facts

- Die Authentifizierung mit Passkeys verwendet zwei **Zeremonien** (Ceremonies): Registrierung (Attestation) und Login (Assertion), für die jeweils eine vom Server generierte, zufällige Challenge erforderlich ist, die vom Authenticator signiert wird.
- **PublicKeyCredentialCreationOptions** regelt die Passkey-Registrierung, während **PublicKeyCredentialRequestOptions** den Login regelt. Beide Objekte werden serverseitig generiert und enthalten die Challenge, die vom Authenticator signiert werden soll.
- **Conditional UI** zeigt verfügbare Passkeys als Autofill-Vorschläge an, erfordert jedoch Discoverable Credentials (Resident Keys) und wird nicht von allen Betriebssystem- und Browser-Kombinationen unterstützt.
- Die **Relying Party ID (rpID)** bindet einen Passkey an eine Domain: Die Authentifizierung ist nur erfolgreich, wenn die URL übereinstimmt oder eine Non-Public-Suffix-Subdomain der rpID ist.
- Passkeys verwenden **COSE-Algorithmen** für die Schlüsselgenerierung, wobei der spezifische Algorithmus im Attribut parsedCredentialPublicKey des Attestation-Objekts aufgezeichnet wird.

## 1. WebAuthn-Zeremonien

Die Authentifizierung mit Passkeys basiert auf den zwei Prozessen, auch Zeremonien (Ceremonies) genannt, **Registrierung** (auch **Attestation-Phase**) und **Login** (auch **Assertion-Phase**).\
Jede Phase erfordert eine vom Server generierte zufällige Challenge, die vom Authenticator signiert und an den WebAuthn-Server zurückgesendet wird, um den Benutzer zu verifizieren.

### 1.1 Registrierung (Attestation)

![Prozessablauf der Registrierungszeremonie in WebAuthn](https://www.corbado.com/website-assets/65fad0076e7b4367976ee993_cs_1_1_registration_flow_min_26eb12d652.png)_Die Registrierungszeremonie verwendet zwei zentrale Objekte: PublicKeyCredentialCreationOptions und Attestation._

[Watch on YouTube](https://www.youtube.com/watch?v=0hRYXHESA24)

### 1.2 Login (Assertion)

![Prozessablauf der Login-Zeremonie in WebAuthn](https://www.corbado.com/website-assets/65fad0f2e412e9ad9d2a5bf1_cs_1_2_login_flow_min_2aaefc04dd.png)_Die Login-Zeremonie verwendet zwei zentrale Objekte: PublicKeyCredentialRequestOptions und Assertion._

## 2. Wichtige Objekte

Für die Registrierung und den Login mit Passkeys gibt es vier Hauptobjekte:

- PublicKeyCredentialCreationOptions
- PublicKeyCredentialRequestOptions
- attestation
- assertion

In diesem Abschnitt wird auch das Objekt authenticatorSelection erklärt, das in den PublicKeyCredentialCreationOptions verwendet wird.

### 2.1 Public Key Credential Creation Options

PublicKeyCredentialCreationOptions ist das zentrale Objekt der Attestation-Phase (Registrierung). Es wird vom [WebAuthn-Server](#webauthn-server) erstellt und von diesem zurückgegeben.

```json
{
    "PublicKeyCredentialCreationOptions": {
        "rp": {
            "id": "passkeys.eu",
            "name": "Corbado Passkeys Demo"
        },
        "user": {
            "displayName": "john.doe",
            "id": "dXNyLZ….DU10Tc",
            "name": "john@doe.com"
        },
        "challenge": "888fix4Bus...pHHr3Y",
        "pubKeyCredParams": [
            {
                "alg": -7,
                "type": "public-key"
            },
            {
                "alg": -257,
                "type": "public-key"
            }
        ],
        "excludeCredentials": [],
        "authenticatorSelection": {
            "authenticatorAttachment": "platform",
            "residentKey": "required",
            "userVerification": "required"
        },
        "attestation": "none",
        "extensions": {}
    }
}
```

Das Objekt enthält folgende Attribute:

- **rp:** Identifiziert die Relying Party (= den Server, der den Benutzer authentifizieren möchte), siehe Abschnitt [4.2 Relying Party ID (rpID)](#relying-party-id).
- **user:** Enthält Daten über das Benutzerkonto, das die Attestation anfordert. Die ID ist eine von der Relying Party gewählte Bytekette, die keine persönlichen Informationen enthalten darf. Der Benutzername oder die E-Mail-Adresse wird stattdessen im Attribut name oder displayName gespeichert. Lesen Sie mehr dazu in Abschnitt [4.1 Datenbankschema](#database-schema).
- **challenge:** Eine zufällig generierte base64URL-kodierte BufferSource, die vom Authenticator signiert werden muss.
- **pubKeyCredParams:** Spezifische Attribute des zu erstellenden Credentials, in der Regel die unterstützten Algorithmen.
- **timeout:** Optionale Zeit in Millisekunden, die der Client auf den Abschluss des Aufrufs warten soll.
- **excludeCredentials:** Optionale Liste von Credentials, um die Erstellung mehrerer Passkeys auf einem Gerät zu begrenzen.
- **authenticatorSelection:** Optionale Auswahl des verwendeten Authenticators für die Methode, z. B. ob ein residentKey erforderlich ist. Siehe [2.5 authenticatorSelection](#authenticatorSelection).
- **attestation:** Kann verwendet werden, um anzufordern, dass das Attestation-Objekt in einer bestimmten Form an die Relying Party weitergegeben wird. Mögliche Werte sind none (Standard), indirect, direct und enterprise.
- **extensions:** Optionale Anfrage(n) für zusätzliche Verarbeitung, wie z. B. spezifische Rückgabewerte. z. B.
    - _credProbs_ fordert Informationen darüber an, ob das erstellte Credential Discoverable (auffindbar) ist
    - _prf_ ermöglicht der Relying Party die Verwendung von Ausgaben einer Pseudo-Random-Function (PRF), die mit einem Credential verknüpft ist

### 2.2 Public Key Credential Request Options

PublicKeyCredentialRequestOptions ist das zentrale Objekt der Assertion-Phase (Login). Es wird vom [WebAuthn-Server](#webauthn-server) erstellt und von diesem zurückgegeben.

```json
{
    "publicKeyCredentialRequestOptions": {
        "challenge": "pT7HMA-…dFPHk",
        "timeout": 500,
        "rpId": "passkeys.eu",
        "userVerification": "preferred",
        "allowCredentials": [],
        "extensions": []
    }
}
```

Das Objekt enthält folgende Attribute:

- **challenge, timeout, extensions:** siehe [oben](#creationoptions).
- **rpId:** Die Kennung der Relying Party für die Assertion-Anforderung, siehe Abschnitt [4.2 Relying Party ID (rpID)](#relying-party-id).
- **allowCredentials:** Optionale Liste von Credentials, die für die Authentifizierung zugelassen sind und die Präferenz des Aufrufers in absteigender Reihenfolge angeben. Diese Liste würde mit PublicKeyCredentialDescriptors gefüllt werden.
- **userVerification:** Optionaler Wert zur Angabe der Anforderungen an die Benutzerverifizierung während des Vorgangs. Mögliche Werte sind preferred (Standard), required oder discouraged.

### 2.3 Attestation

Während der **Attestation** / Registrierungszeremonie gibt der Authenticator diese **Registration Response** zurück. Sie können dies selbst im [Passkeys Debugger](https://www.passkeys-debugger.io/) ausprobieren.

```json
{
    "authenticatorAttachment": "platform",
    "id": "JKZbixUfKN_aZtimefYT-OjH5dw",
    "rawId": "JKZbixUfKN_aZtimefYT-OjH5dw",
    "response": {
        "attestationObject": {
            "fmt": "none",
            "attStmt": {},
            "authData": {
                "rpIdHash": "PpZrl-Wqt-OFfBpyy2SraN1m7LT0GZORwGA7-6ujYkM",
                "flags": {
                    "userPresent": true,
                    "userVerified": true,
                    "backupEligible": true,
                    "backupStatus": true,
                    "attestedData": true,
                    "extensionData": false
                },
                "counter": 0,
                "aaguid": {
                    "raw": "fbfc3007-154e-4ecc-8c0b-6e020557d7bd",
                    "name": "iCloud Keychain"
                },
                "credentialID": "JKZbixUfKN_aZtimefYT-OjH5dw",
                "credentialPublicKey": "pQECAyYgASFYIPWLalDzyxIDmAADvfK8iNM5To50kh7TyPH-teEz8RMdIlgg3D7bPIWQJ8z-WFn3zdYZzJw9c7mhPdmflQqD9vV7efA",
                "parsedCredentialPublicKey": {
                    "keyType": "EC2 (2)",
                    "algorithm": "ES256 (-7)",
                    "curve": 1,
                    "x": "9YtqUPPLEgOYAAO98ryI0zlOjnSSHtPI8f614TPxEx0",
                    "y": "3D7bPIWQJ8z-WFn3zdYZzJw9c7mhPdmflQqD9vV7efA"
                }
            }
        },
        "clientDataJSON": {
            "type": "webauthn.create",
            "challenge": "k2p6f-upzP_hc6NZvmMAxiI0VSTeQIeXXVRGW62LTj0",
            "origin": "https://www.passkeys-debugger.io",
            "crossOrigin": false
        },
        "transports": ["hybrid", "internal"],
        "authenticatorData": "PpZrl-Wqt-OFfBpyy2SraN1m7LT0GZORwGA7-6ujYkNdAAAAAPv8MAcVTk7MjAtuAgVX170AFCSmW4sVHyjf2mbYpnn2E_jox-XcpQECAyYgASFYIPWLalDzyxIDmAADvfK8iNM5To50kh7TyPH-teEz8RMdIlgg3D7bPIWQJ8z-WFn3zdYZzJw9c7mhPdmflQqD9vV7efA",
        "publicKey": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE9YtqUPPLEgOYAAO98ryI0zlOjnSSHtPI8f614TPxEx3cPts8hZAnzP5YWffN1hnMnD1zuaE92Z-VCoP29Xt58A",
        "publicKeyAlgorithm": -7
    },
    "type": "public-key",
    "clientExtensionResults": {}
}
```

Die **Attestation** enthält einige wichtige Komponenten wie das [attestationObject](#attestationObject), den [algorithm](#algorithm) und die [transport](#transport)-Flags.

#### 2.3.1 attestationObject

![Das attestationObject ist Teil der Attestation in WebAuthn](https://www.corbado.com/website-assets/65fad76914987b84f3ecf4cd_cs_2_3_attestation_Object_min_12a3b9e5cc.png)

Entnommen aus der [WebAuthn-Spezifikation des W3C](https://www.w3.org/TR/webauthn-2/#attestation-object)

Das **attestationObject** ist ein CBOR-kodiertes Objekt, das Informationen über die neu erstellten Credentials, den öffentlichen Schlüssel (Public Key) und andere relevante Daten enthält:

- **fmt** wird für Passkeys typischerweise als "none" ausgewertet
- **attStmt** ist für Passkeys leer und für andere Authenticatoren gefüllt, z. B. Hardware-Sicherheitsschlüssel (Security Key)
- **authData** ist ein Puffer von Werten, der die folgenden Daten enthält:

![authData ist ein Puffer von Werten, der z.B. Flags, Zähler und Erweiterungen enthält](https://www.corbado.com/website-assets/65fc7c70babae11893e3e1e1_cs_2_3_auth_Data_min_7a7d39d083.png)

Lesen Sie mehr über die [Erweiterungen (Extensions)](https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API/WebAuthn_extensions).

#### algorithm

Passkeys werden mit **COSE-Algorithmen** generiert, wobei der verwendete Algorithmus im **algorithm-Attribut** von parsedCredentialPublicKey im [Attestation-Objekt](#attestation) angegeben ist.\
Hier ist eine Übersicht der relevantesten COSE-Algorithmen:

![Passkeys werden mit COSE-Algorithmen generiert](https://www.corbado.com/website-assets/65fade5ce80ed150f88b59fb_cs_2_3_COSE_algorithms_min_f0d1a5f931.png)

#### 2.3.2 transport

Die Eigenschaft **transports** gibt die Mechanismen an, über die ein Authenticator mit einem Client kommunizieren kann. Einige gängige, beispielhafte Wertekombinationen sind:

- **"transports": \["internal","hybrid"]**: Passkeys können vom Plattform-Authenticator (z. B. Face ID, Touch ID, Windows Hello) oder über Cross-Device-Authentifizierung (mithilfe von QR-Code & Bluetooth) verwendet werden.
- **"transports": \["internal"]**: Passkeys können nur vom Plattform-Authenticator verwendet werden (z. B. Face ID, Touch ID, Windows Hello).
- **Keine Eigenschaft "transports" festgelegt:** Standardverhalten, das keine Hinweise liefert.

### 2.4 Assertion

Während der **Assertion** / Login-Zeremonie gibt der Authenticator diese **Login Response** zurück. Sie können dies selbst im [Passkeys Debugger](https://www.passkeys-debugger.io/) ausprobieren.

```json
{
    "id": "JKZbixUfKN_aZtimefYT-OjH5dw",
    "rawId": "JKZbixUfKN_aZtimefYT-OjH5dw",
    "type": "public-key",
    "authenticatorAttachment": "platform",
    "response": {
        "authenticatorData": {
            "rpIdHash": "PpZrl-Wqt-OFfBpyy2SraN1m7LT0GZORwGA7-6ujYkM",
            "flags": {
                "userPresent": true,
                "userVerified": true,
                "backupEligible": true,
                "backupStatus": true,
                "attestedData": false,
                "extensionData": false
            },
            "counter": 0
        },
        "clientDataJSON": {
            "type": "webauthn.get",
            "challenge": "GCVkITWbe2l2dttsn_DgJYvH9QPHPDo0ygWgcgI6B7U",
            "origin": "https://www.passkeys-debugger.io",
            "crossOrigin": false,
            "other_keys_can_be_added_here": "do not compare clientDataJSON against a template. See https://goo.gl/yabPex"
        },
        "signature": "MEQCIA-orC8N2KKWOxyY17BWP8lB-Be5to9btXRnJZf2SLhXAiBGxJe5Eu5LwOTbsyzAYmIXHOhlC3pN7s7Q1fRLvEW57g",
        "userHandle": "_FKz1uwqmR_3yGq6hJntzoIFwFC_d1u_53YRELh0KlE"
    }
}
```

Die **Assertion** enthält einige wichtige Komponenten wie Flags, Signatur und userHandle.

#### 2.4.1 flags

Hier ist eine Übersicht der wichtigsten **Flags** und ihrer Kombinationen:

![Die wichtigsten Flags sind userPresent, userVerified, backupEligible, backupStatus](https://www.corbado.com/website-assets/65fc7ca5a6a6fb1f3e66b514_cs_2_4_flags_min_19e5ddc4ce.png)

#### 2.4.2 signature

Die **Signatur** wird verwendet, um zu verifizieren, dass der Benutzer, der versucht sich anzumelden, tatsächlich den privaten Schlüssel (Private Key) besitzt. Die Signatur wird erstellt, indem die authenticatorData und der clientDataHash (d. h. die SHA-256-Version des ClientDataJSON) verkettet werden und das Ergebnis mit dem privaten Schlüssel (im Authenticator) signiert wird. Zur Verifizierung mit dem öffentlichen Schlüssel verketten wir ebenfalls authenticatorData und clientDataHash. Wenn das Verifizierungsergebnis wahr zurückgibt, ist die Authentifizierung erfolgreich.

![Die Signatur wird verwendet, um den privaten Schlüssel zu verifizieren](https://www.corbado.com/website-assets/65fae2ad96200e9576992209_cs_2_4_signature_min_36b9b8ccbe.png)

#### 2.4.3 userHandle

Der **userHandle** ist die eigentliche user_id. Lesen Sie mehr über die user_id im Abschnitt [**4.1 Datenbankschema**](#database-schema).

### 2.5 authenticatorSelection

Das Objekt **authenticatorSelection** ermöglicht es dem Server, Einstellungen für den Authenticator und die Erstellung von Credentials mit den folgenden Werten vorzuschreiben:

#### 2.5.1 authenticatorAttachment

- **Platform:** Der Authenticator ist an die Plattform des Clients gebunden und daher nicht abnehmbar.
- **Cross-platform:** Der Authenticator ist nicht an die Plattform des Clients gebunden und kann auf mehreren Geräten verwendet werden.

#### 2.5.2 residentKey

- **Required:** Der Authenticator muss einen Resident Key erstellen (falls nicht möglich, sollte die Operation fehlschlagen).
- **Preferred:** Der Authenticator sollte versuchen, einen Resident Key zu erstellen (falls nicht möglich, sollte er einen Non-Resident Key erstellen).
- **Discouraged:** Der Authenticator muss einen Non-Resident Key erstellen (falls nicht möglich, sollte die Operation fehlschlagen).

> **Resident Keys (auch Discoverable Credential genannt):** Resident Keys werden auf dem Authenticator gespeichert und während der Authentifizierung abgerufen. Auf diese Weise kann der Client eine Liste möglicher Schlüssel ermitteln, weshalb [Conditional UI](https://www.corbado.com/blog/user-transition-passkeys-&gt; conditional-ui) Resident Keys erfordert.
> **Non-Resident Keys (auch Non-Discoverable Credential genannt):** Bei Non-Resident Keys wird die Credential ID auf dem Server gespeichert und während der Authentifizierung bereitgestellt. Die Credential ID ist ein [opaker Identifikator](https://www.w3.org/TR/webauthn-3/#sctn-credential-id), dessen interne Struktur implementierungsspezifisch ist – Authenticatoren können private Schlüssel direkt speichern, verschlüsseltes Key-Wrapping verwenden oder Schlüssel aus internen Geheimnissen ableiten. Der genaue Mechanismus variiert je nach Authenticator-Implementierung.

#### 2.5.3 userVerification

- **Required:** Der Vorgang sollte den Benutzer verifizieren.
- **Preferred:** Der Vorgang sollte den Benutzer verifizieren, kann jedoch ohne diese Verifizierung fortgesetzt werden (Standardoption).
- **Discouraged:** Der Vorgang sollte den Benutzer nicht verifizieren.

> **Warnung:** Wenn auf "**Preferred"** gesetzt, können der Benutzer oder sein Gerät die Benutzerverifizierung im Authentifizierungsprozess überspringen (lesen Sie mehr in diesem [Artikel](https://web.dev/articles/passkey-form-autofill)).

## 3. Conditional UI

**Conditional UI** (Passkey-Autofill) zeigt dem Benutzer verfügbare Passkeys in einem Auswahl-Dropdown an, wenn ein Benutzer einen Resident Key bei der Relying Party registriert hat. Es verbessert die Benutzerfreundlichkeit von Passkeys, erfordert jedoch zusätzliche Entwicklungsaufwände und ist nicht für alle OS / Browser-Kombinationen verfügbar.

### 3.1 Login-Ablauf mit Conditional UI

![Prozessablauf eines Logins mit Conditional UI in WebAuthn](https://www.corbado.com/website-assets/65fae71a75d50f6ba14041d9_cs_3_1_conditional_ui_flow_min_394a12f521.png)_Wie bei einem regulären Login verwendet Conditional UI auch die Objekte PublicKeyCredentialRequestOptions und Assertion._

### 3.2 Gerätekompatibilität

Conditional UI ist (noch) nicht auf allen Kombinationen von Betriebssystemen und Browsern verfügbar. Hier ist ein Überblick über die aktuelle Browserabdeckung (März 2024):

![Tabelle, die die Verfügbarkeit von Conditional UI auf OS/Browser-Kombinationen zeigt](https://www.corbado.com/website-assets/65fae8d6321e72be11445913_cs_3_2_conditional_ui_compatibility_min_d5767f13b3.png)

Für eine aktuelle Übersicht siehe [diese Website](https://caniuse.com/mdn-api_publickeycredential_isconditionalmediationavailable_static).

### 3.3 Code-Beispiele

#### 3.3.1 Conditional UI-Methode

Ein vollständiger, minimalistischer Code für eine Conditional UI-Methode sieht so aus:

```html
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Conditional UI</title>
    </head>
    <body>
        <input type="text" id="username" autocomplete="username webauthn" />

        <script>
            async function passkeyLogin() {
                try {
                    // retrieve the request options (incl. the challenge) from the WebAuthn server
                    let options = await WebAuthnClient.getPublicKeyRequestOptions();

                    const credential = await navigator.credentials.get({
                        publicKey: options.publicKeyCredentialRequestOptions,
                        mediation: "conditional",
                    });

                    const userData = await WebAuthnClient.sendSignedChallenge(credential);
                    window.location.href = "/logged-in";
                } catch (error) {
                    console.log(error);
                }
            }

            passkeyLogin();
        </script>
    </body>
</html>
```

#### 3.3.2 Browser-Kompatibilitätsprüfung

Conditional UI funktioniert nur mit **Resident Keys** / Discoverable Credentials.\
Es wird empfohlen, einen **anderen Server-Endpunkt** bereitzustellen, um den Conditional UI-Login zu starten.\
Der Client muss mehrere Anforderungen erfüllen:

- Der Browser muss Conditional UI unterstützen (siehe [3.2 Gerätekompatibilität](#device-compatibility)).
- JavaScript muss aktiviert sein und die Webseite muss ein HTML-Eingabefeld bereitstellen.
- Timeout-Parameter sollten ignoriert werden.

Um Fehler zu vermeiden, sollte der Server zuerst die Verfügbarkeit des Clients mit dieser Funktion testen:
Im realen Datenverkehr treten Erkennungs- und Lebenszyklusprobleme oft als `NotAllowedError` oder `AbortError` auf. Nutzen Sie diesen WebAuthn-Fehler-Leitfaden für die Klassifizierung in erwartete vs. unerwartete Fehler, einschließlich nativer Credential Manager Passkey-Fehler.

```javascript
// source: https://developer.mozilla.org/en-US/docs/Web/API/PublicKeyCredential/isConditionalMediationAvailable#examples

// 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 start endpoint

        let options = await WebAuthnClient.getPublicKeyRequestOptions();

        const credential = await navigator.credentials.get({
            publicKey: options.publicKeyCredentialRequestOptions,
            mediation: "conditional",
        });
        /*
    ...
    */
    }
}
```

#### 3.3.3 Autocomplete-Token in Eingabefeldern

Das Eingabefeld sollte ein HTML-Autofill-Token erhalten, das dem Client signalisiert, Passkeys für die laufende Anfrage auszufüllen. Neben Passkeys können die Autofill-Token mit vorhandenen Token kombiniert werden, z. B. Benutzernamen und Passwörtern:

- autocomplete="username webauthn": Zeigt nicht nur Passkeys an, sondern schlägt auch das automatische Ausfüllen des Benutzernamens vor.
- autocomplete="current-password webauthn": Zeigt nicht nur Passkeys an, sondern fordert außerdem zum automatischen Ausfüllen des Passworts auf.

```html
<label for="name">Username:</label>
<input type="text" name="name" autocomplete="username webauthn" />
<label for="password">Password:</label>
<input type="password" name="password" autocomplete="current-password webauthn" />
```

## 4. WebAuthn-Server

### 4.1 Datenbankschema

Es gibt kein obligatorisches oder standardisiertes Datenbankschema für WebAuthn-Server. Dieses beispielhafte Datenbankschema kann jedoch verwendet werden, um die erforderlichen Informationen zu speichern und alle Funktionen eines WebAuthn-Servers bereitzustellen:

![Beispielhaftes Datenbankschema für einen WebAuthn-Server, das Daten für 'user' und 'credential'](https://www.corbado.com/website-assets/65fc7cda64ff7798cdbb2dfc_cs_4_1_database_schema_min_8ac4536120.png)_Fett gedruckte Attribute sind für eine minimal funktionsfähige Implementierung obligatorisch, während die anderen nur für optionale, aber hilfreiche Funktionen benötigt werden._

#### 4.1.1 Authentifizierungsrelevante Daten

- **Credential ID:** Dies ist eine eindeutige ID, die vom Authenticator während der Registrierung eines Passkeys generiert wird. Sie sollte verwendet werden, um das tatsächliche Benutzerkonto nachzuschlagen, das mit dem Passkey verknüpft ist. Zusätzlich sollte dann der userHandle (von user_id) verglichen werden, um das für die Authentifizierung verwendete Konto zu validieren. Verwenden Sie das Attribut user.name nicht für Vergleiche, da es sich im Laufe der Zeit ändern kann.
- **User ID (user_id):** Eine von der Relying Party festgelegte eindeutige ID, um ein Benutzerkonto in ihrem System darzustellen. Sie wird als userHandle innerhalb des Assertion-Objekts zurückgegeben.

#### 4.1.2 Metadaten für die Anzeige und Auswahl von Passkeys:

- **User DisplayName (user.displayName):** Benutzerfreundlicher, lesbarer Name, der normalerweise der vollständige Name des Benutzers ist. Er wird dem Benutzer angezeigt, jedoch nicht während der Authentifizierung verwendet.

- **User Name (user.name):** Eindeutiger und lesbarer Name, der normalerweise eine E-Mail-Adresse oder ein Benutzername ist. Er kann dem Benutzer angezeigt werden, wird jedoch nicht während der Authentifizierung verwendet.

### 4.2 Relying Party ID (rpId)

Die **Relying Party ID (rpID)** ist eine Domäne, die innerhalb des Passkeys gespeichert ist und sicherstellt, dass der Passkey nur für die korrekte Domäne funktioniert (Browser-URL, siehe diesen Artikel für native Apps). Während der Authentifizierung wird die rpID gegen die Browser-URL geprüft und nur in diesen beiden Fällen zugelassen:

1. Die URL stimmt exakt mit der rpId überein ODER
2. Die URL ist eine Subdomain, die mit der rpId übereinstimmt, und die übergeordnete Domain steht nicht auf der Public Suffix List.

Hier sind Beispiele für (un-)zulässige Kombinationen:

![Beispiele für zugelassene und nicht zugelassene Kombinationen von Relying Party IDs](https://www.corbado.com/website-assets/65fc7d099bf36909d7f40495_cs_4_2_rpid_examples_min_55f5750e90.png)

## 5. Hilfreiche Websites und Tools

Hier ist eine Liste nützlicher Tools & Websites zur Implementierung von Passkeys.

- [**Passkeys Debugger:**](https://www.passkeys-debugger.io/) Tool zum Debuggen der WebAuthn Responses als JSON und zum Testen von WebAuthn-Operationen mit verschiedenen Optionen.
- [**Passkeys Glossar:**](https://www.corbado.com/glossary) Erklärung von Begriffen & Konzepten rund um Passkeys.
- [**WebAuthn-Spezifikation:**](https://www.w3.org/TR/webauthn-2/) Dies ist die offizielle WebAuthn-Spezifikation.
- [**Chrome Device Log:**](http://chrome://device-log) Tool zur Anzeige eines Protokolls der WebAuthn-Operationen Ihres Geräts (nur in Chrome über `chrome://device-log` verfügbar).

Für Strategien zur Optimierung Ihrer Passkey-UX über die technische Implementierung hinaus, lesen Sie unsere Leitfäden zu Best Practices für die Passkey-Erstellung und Best Practices für den Passkey-Login.

Wenn Sie Passkeys mit nur wenigen Codezeilen in eine beliebige Anwendung implementieren möchten, können Sie auch [Corbado Complete](https://docs.corbado.com/start) (für neue Apps) oder [Corbado Connect](https://www.corbado.com/enterprise) (für bestehende Apps) verwenden.

## Häufig gestellte Fragen (FAQ)

### Wie implementiere ich Conditional UI für das Passkey-Autofill in meiner Web-App?

Conditional UI erfordert eine Überprüfung der Browser-Unterstützung über `PublicKeyCredential.isConditionalMediationAvailable()`, bevor die Authentifizierung initiiert wird. Das Eingabefeld muss das HTML-Token `autocomplete="username webauthn"` enthalten und der Benutzer muss über einen registrierten Resident Key (Discoverable Credential) verfügen. Es wird ein separater Server-Endpunkt empfohlen, um den Conditional UI-Login-Ablauf abzuwickeln.

### Was sind die minimalen Daten, die ich in meiner Datenbank speichern muss, um die WebAuthn-Authentifizierung zu unterstützen?

Speichern Sie mindestens die Credential ID, die während der Registrierung vom Authenticator generiert wurde, und die User ID (user_id), die als userHandle im Assertion-Objekt zurückgegeben wird. Verwenden Sie die Credential ID, um das zugehörige Benutzerkonto nachzuschlagen, und vergleichen Sie den userHandle, um die Authentifizierung zu validieren. Vermeiden Sie die Verwendung von user.name für Vergleiche, da sich dieser im Laufe der Zeit ändern kann.

### Was ist der Unterschied zwischen Resident Keys und Non-Resident Keys in WebAuthn?

Resident Keys (Discoverable Credentials) werden auf dem Authenticator selbst gespeichert und während der Authentifizierung abgerufen. Dies ist erforderlich, damit Conditional UI funktioniert. Bei Non-Resident Keys wird die Credential ID auf dem Server gespeichert und während der Authentifizierung an den Authenticator gesendet. Das Feld residentKey in authenticatorSelection steuert dieses Verhalten mit den Werten "required", "preferred" oder "discouraged".

### Wie funktioniert userVerification und was sind die Risiken, wenn sie auf preferred gesetzt wird?

Das Feld userVerification steuert, ob der Authenticator den Benutzer während der Anmeldung verifizieren muss. Die möglichen Werte sind "required", "preferred" (Standard) oder "discouraged". Wenn der Wert auf "preferred" gesetzt ist, können der Benutzer oder sein Gerät die Überprüfung während des Authentifizierungsprozesses vollständig überspringen, was die Sicherheit schwächen kann. Durch die Einstellung auf "required" wird sichergestellt, dass die Überprüfung immer erfolgt, bevor die Authentifizierung abgeschlossen ist.
