Signatur
Beschreibung
Die statische Methode PublicKeyCredential.parseRequestOptionsFromJSON() wird bei der Anmeldung mit Passkeys bzw. WebAuthn gebraucht. Server liefern die Anmeldeoptionen meist als JSON. Binärfelder wie challenge oder allowCredentials[].id stehen darin als Base64url-Strings. Die WebAuthn-API erwartet an diesen Stellen aber ArrayBuffer-Werte. Die Methode übernimmt die Umwandlung und gibt ein Objekt zurück, das du direkt als publicKey-Option an navigator.credentials.get() übergeben kannst.
Vorher mussten Entwickler eigene Base64url-Decoder schreiben oder Bibliotheken wie @github/webauthn-json einsetzen. Die eingebaute Methode ersetzt diesen Code und folgt dem Format, das die WebAuthn-Spezifikation als PublicKeyCredentialRequestOptionsJSON festlegt. Das Gegenstück für die Registrierung ist PublicKeyCredential.parseCreationOptionsFromJSON(). Für die Rückrichtung, also das Serialisieren der Antwort an den Server, gibt es PublicKeyCredential.prototype.toJSON().
Typischer Ablauf: Der Client holt die Optionen vom Server, wandelt sie mit dieser Methode um, ruft navigator.credentials.get({ publicKey }) auf und schickt das Ergebnis als credential.toJSON() zur Prüfung zurück an den Server.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $options Pflicht | PublicKeyCredentialRequestOptionsJSON (Object) | Objekt mit den Anmeldeoptionen im JSON-Format. challenge ist Pflicht (Base64url-String). Optional sind timeout, rpId, allowCredentials (Array aus { id, type, transports }, id als Base64url), userVerification, hints und extensions. |
Rückgabewert
challenge und allowCredentials[].id (sowie passende Erweiterungsfelder) sind darin zu ArrayBuffer dekodiert. Es kann direkt als publicKey an navigator.credentials.get() übergeben werden.Beispiele
JSON-Optionen umwandeln und Aufbau prüfen
const json = {
challenge: 'cmFuZG9tLWNoYWxsZW5nZS0xMjM',
rpId: 'example.com',
timeout: 60000,
userVerification: 'preferred',
allowCredentials: [
{ type: 'public-key', id: 'Y3JlZC1pZC1hYmM', transports: ['internal', 'hybrid'] }
]
};
const options = PublicKeyCredential.parseRequestOptionsFromJSON(json);
console.log(options.challenge instanceof ArrayBuffer);
console.log(options.allowCredentials[0].id.byteLength);
console.log(options.rpId);
Vollständiger Passkey-Login mit Server-Roundtrip
const loginWithPasskey = async () => {
// 1. Optionen vom Server laden
const res = await fetch('/webauthn/login/options', { method: 'POST' });
const optionsJSON = await res.json();
// 2. In WebAuthn-kompatibles Format umwandeln
const publicKey = PublicKeyCredential.parseRequestOptionsFromJSON(optionsJSON);
// 3. Authenticator anfragen
const credential = await navigator.credentials.get({ publicKey });
// 4. Antwort serialisiert an den Server zurückschicken
const verify = await fetch('/webauthn/login/verify', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(credential.toJSON())
});
return verify.ok;
};
loginWithPasskey().then((ok) => console.log(ok ? 'Angemeldet' : 'Fehlgeschlagen'));
Feature-Erkennung mit Fallback
const toRequestOptions = (json) => {
if (typeof PublicKeyCredential?.parseRequestOptionsFromJSON === 'function') {
return PublicKeyCredential.parseRequestOptionsFromJSON(json);
}
// Fallback: Base64url manuell dekodieren
const decode = (s) => {
const b64 = s.replace(/-/g, '+').replace(/_/g, '/').padEnd(Math.ceil(s.length / 4) * 4, '=');
return Uint8Array.from(atob(b64), (c) => c.charCodeAt(0)).buffer;
};
return {
...json,
challenge: decode(json.challenge),
allowCredentials: json.allowCredentials?.map((c) => ({ ...c, id: decode(c.id) }))
};
};
const opts = toRequestOptions({ challenge: 'YWJj' });
console.log(new Uint8Array(opts.challenge));
// Wichtig · Fallstricke
- Browser-Unterstützung: Die Methode ist relativ neu (WebAuthn Level 3). Ältere Browser kennen sie nicht. Prüfe daher mit Feature-Erkennung und halte einen Fallback bereit.
- Ungültige Eingabe: Fehlt
challengeoder ist ein Feld kein gültiger Base64url-String (z. B. klassisches Base64 mit+,/oder=-Auffüllung), wird eineEncodingError-DOMExceptionbzw. einTypeErrorgeworfen. Fange den Aufruf deshalb mittry…catchab. - Nur Umwandlung, keine Prüfung: Die Methode prüft keine Sicherheitseigenschaften. Die Challenge muss der Server zufällig erzeugen, nur einmal verwenden und bei der Antwort serverseitig prüfen.
- Sicherer Kontext:
PublicKeyCredentialgibt es nur in sicheren Kontexten (HTTPS oderlocalhost).rpIdmuss zur aktuellen Domain passen, sonst schlägtnavigator.credentials.get()mitSecurityErrorfehl. - Für die Registrierung gibt es das Gegenstück
parseCreationOptionsFromJSON(). Die beiden sind nicht austauschbar.