Signatur
Beschreibung
Die Methode toJSON() wandelt ein PublicKeyCredential, das Sie von navigator.credentials.create() (Registrierung) oder navigator.credentials.get() (Anmeldung) erhalten, in ein einfaches JavaScript-Objekt um. Alle ArrayBuffer-Felder wie rawId, clientDataJSON, attestationObject, authenticatorData oder signature werden dabei als Base64URL-kodierte Strings ausgegeben.
Damit entfällt die bisher übliche, fehleranfällige Handarbeit mit Hilfsfunktionen, die Puffer manuell kodieren. Das Ergebnis kann direkt mit JSON.stringify() serialisiert und per fetch() an den Server (die Relying Party) geschickt werden. Da JSON.stringify() eine vorhandene toJSON()-Methode automatisch aufruft, genügt oft sogar JSON.stringify(credential).
Die Form des Ergebnisses hängt vom Vorgang ab:
- Registrierung (
AuthenticatorAttestationResponse):RegistrationResponseJSONmitresponse.clientDataJSON,response.attestationObject,response.transports, ggf.publicKey,publicKeyAlgorithmundauthenticatorData. - Anmeldung (
AuthenticatorAssertionResponse):AuthenticationResponseJSONmitresponse.clientDataJSON,response.authenticatorData,response.signatureund ggf.response.userHandle.
Zusätzlich enthalten beide Varianten id, rawId, type ("public-key"), authenticatorAttachment sowie clientExtensionResults. Das Gegenstück für die Eingangsseite sind die statischen Methoden PublicKeyCredential.parseCreationOptionsFromJSON() und parseRequestOptionsFromJSON().
Rückgabewert
RegistrationResponseJSON, bei Anmeldung ein AuthenticationResponseJSON.Beispiele
Passkey registrieren und an den Server senden
const registerPasskey = async () => {
// Optionen vom Server holen (JSON mit Base64URL-Werten)
const optionsJSON = await (await fetch('/webauthn/register/options')).json();
const publicKey = PublicKeyCredential.parseCreationOptionsFromJSON(optionsJSON);
const credential = await navigator.credentials.create({ publicKey });
// In JSON-taugliche Form umwandeln
const payload = credential.toJSON();
console.log(payload.type, typeof payload.response.attestationObject);
await fetch('/webauthn/register/verify', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
});
};
registerPasskey();
Anmeldung: JSON.stringify ruft toJSON() automatisch auf
const login = async () => {
const optionsJSON = await (await fetch('/webauthn/login/options')).json();
const publicKey = PublicKeyCredential.parseRequestOptionsFromJSON(optionsJSON);
const assertion = await navigator.credentials.get({ publicKey });
// Kein expliziter toJSON()-Aufruf nötig
const body = JSON.stringify(assertion);
console.log(Object.keys(JSON.parse(body).response));
const res = await fetch('/webauthn/login/verify', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body
});
return res.ok;
};
Feature-Erkennung mit manuellem Fallback
const toBase64Url = (buffer) =>
btoa(String.fromCharCode(...new Uint8Array(buffer)))
.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
const serializeAssertion = (cred) => {
if (typeof cred.toJSON === 'function') {
return cred.toJSON();
}
// Fallback für ältere Browser
return {
id: cred.id,
rawId: toBase64Url(cred.rawId),
type: cred.type,
authenticatorAttachment: cred.authenticatorAttachment ?? null,
clientExtensionResults: cred.getClientExtensionResults(),
response: {
clientDataJSON: toBase64Url(cred.response.clientDataJSON),
authenticatorData: toBase64Url(cred.response.authenticatorData),
signature: toBase64Url(cred.response.signature),
userHandle: cred.response.userHandle
? toBase64Url(cred.response.userHandle)
: null
}
};
};
// Wichtig · Fallstricke
- Browser-Kompatibilität: Die Methode ist relativ neu (WebAuthn Level 3). Ältere Chrome-, Safari- und mobile Versionen kennen sie nicht – prüfen Sie mit
typeof credential.toJSON === 'function'und halten Sie einen Fallback bereit (oder nutzen Sie eine Bibliothek wie @simplewebauthn/browser). - Base64URL, nicht Base64: Die Werte verwenden
-und_statt+und/und haben kein=-Padding. Der Server muss entsprechend dekodieren. - Keine Rückumwandlung: Es gibt kein
PublicKeyCredential.fromJSON(); das JSON dient ausschließlich der Übertragung zum Server. - Sicherheit: Die Serialisierung ersetzt nicht die serverseitige Prüfung. Challenge, Origin, RP-ID, Signatur und Signaturzähler müssen immer auf dem Server verifiziert werden. Übertragen Sie die Daten nur über HTTPS – WebAuthn funktioniert ohnehin nur in sicheren Kontexten.
clientExtensionResultskann Erweiterungsergebnisse mit Binärdaten (z. B.prf,largeBlob) enthalten; deren Kodierung variiert je nach Browser-Implementierung.