Start · Sprachen · JavaScript · Referenz · CredentialsContainer.create()

CredentialsContainer.create()

Methode

Erstellt ein neues Credential (Passwort, föderiert, Passkey/Public Key oder Identity), das man speichern und später mit <code>navigator.credentials.get()</code> abrufen kann.

seit JavaScript Credential Management Level 1 / WebAuthn Level 1 – Kategorie: webapi

Signatur

CredentialsContainer.prototype.create(options)

Beschreibung

Die Methode create() gehört zu CredentialsContainer und wird über navigator.credentials.create() aufgerufen. Welcher Credential-Typ entsteht, hängt davon ab, welcher Schlüssel im options-Objekt angegeben ist: password erzeugt ein PasswordCredential, federated ein FederatedCredential und publicKey ein PublicKeyCredential (WebAuthn/Passkeys). Pro Aufruf ist genau einer dieser Typen erlaubt.

Am wichtigsten ist die Methode heute bei der Registrierung von Passkeys. Der Browser erzeugt dabei über einen Authenticator (Touch ID, Windows Hello, Sicherheitsschlüssel, Smartphone) ein neues Schlüsselpaar. Der öffentliche Schlüssel und die Attestierung gehen an den Server, der private Schlüssel verlässt den Authenticator nie. Die challenge muss vom Server kommen und wird dort anschließend geprüft.

Bei password und federated erzeugt create() nur das Credential-Objekt und speichert noch nichts. Damit der Passwortmanager des Browsers es übernimmt, muss man es danach an navigator.credentials.store() übergeben. Alternativ kann man die Konstruktoren new PasswordCredential() bzw. new FederatedCredential() direkt benutzen.

Die Methode funktioniert nur in einem sicheren Kontext (HTTPS oder localhost). Sie gibt immer ein Promise zurück, das auch abgelehnt werden kann, z. B. wenn der Nutzer abbricht oder der Authenticator nicht passt.

Parameter

Name Typ Default Beschreibung
$options CredentialCreationOptions {} Objekt, das genau einen Credential-Typ festlegt und optional ein signal enthält.
$options.publicKey PublicKeyCredentialCreationOptions WebAuthn-Optionen: challenge (BufferSource), rp ({ id, name }), user ({ id, name, displayName }), pubKeyCredParams (Algorithmen, z. B. -7 = ES256, -257 = RS256), optional timeout, authenticatorSelection, attestation, excludeCredentials, extensions.
$options.password HTMLFormElement | PasswordCredentialData Ein Formular-Element (Felder brauchen autocomplete-Attribute wie username und current-password) oder ein Objekt mit id, password, optional name und iconURL.
$options.federated FederatedCredentialInit Objekt mit id und provider (URL des Identitätsanbieters), optional name, iconURL und protocol.
$options.signal AbortSignal Mit diesem Signal lässt sich ein laufender Vorgang abbrechen, etwa eine offene WebAuthn-Abfrage.

Rückgabewert

Typ
Promise<Credential | null>
Beschreibung
Ein Promise, das mit einem PublicKeyCredential, PasswordCredential oder FederatedCredential erfüllt wird. Wenn kein Credential erzeugt werden kann, wird es mit null erfüllt. Es wird abgelehnt mit u. a. NotAllowedError (Nutzer bricht ab oder Zeitlimit abgelaufen), InvalidStateError (Authenticator ist schon über excludeCredentials registriert), SecurityError (ungültige rp.id oder unsicherer Kontext), NotSupportedError (kein unterstützter Algorithmus) oder AbortError.

Beispiele

Passkey registrieren (WebAuthn)

// Hilfsfunktionen für Base64URL
const toB64Url = (buf) => btoa(String.fromCharCode(...new Uint8Array(buf)))
  .replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
const fromB64Url = (str) => Uint8Array.from(
  atob(str.replace(/-/g, '+').replace(/_/g, '/')), (c) => c.charCodeAt(0));

const registerPasskey = async () => {
  // Challenge und Nutzerdaten kommen vom Server
  const opts = await (await fetch('/webauthn/register/options')).json();

  const credential = await navigator.credentials.create({
    publicKey: {
      challenge: fromB64Url(opts.challenge),
      rp: { id: location.hostname, name: 'Beispiel GmbH' },
      user: {
        id: fromB64Url(opts.userId),
        name: opts.email,
        displayName: opts.displayName
      },
      pubKeyCredParams: [
        { type: 'public-key', alg: -7 },   // ES256
        { type: 'public-key', alg: -257 }  // RS256
      ],
      authenticatorSelection: {
        residentKey: 'required',
        userVerification: 'preferred'
      },
      timeout: 60000,
      attestation: 'none'
    }
  });

  // Ergebnis zur Prüfung an den Server schicken
  await fetch('/webauthn/register/verify', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      id: credential.id,
      rawId: toB64Url(credential.rawId),
      type: credential.type,
      clientDataJSON: toB64Url(credential.response.clientDataJSON),
      attestationObject: toB64Url(credential.response.attestationObject)
    })
  });
  console.log('Passkey registriert:', credential.type);
};

registerPasskey().catch((err) => console.error(err.name, err.message));
Passkey registriert: public-key

Passwort-Credential aus einem Formular erzeugen und speichern

// <form id="login"> mit <input name="username" autocomplete="username">
// und <input name="password" type="password" autocomplete="current-password">
const form = document.querySelector('#login');

form.addEventListener('submit', async (event) => {
  event.preventDefault();
  const res = await fetch('/login', { method: 'POST', body: new FormData(form) });

  if (res.ok && 'PasswordCredential' in window) {
    const cred = await navigator.credentials.create({ password: form });
    await navigator.credentials.store(cred); // erst store() speichert
    console.log('Gespeichert für', cred.id);
  }
});
Gespeichert für max@example.com

Föderiertes Credential mit Abbruch-Timeout

const controller = new AbortController();
setTimeout(() => controller.abort(), 10000);

const saveFederated = async (email) => {
  if (!('FederatedCredential' in window)) return null;
  const cred = await navigator.credentials.create({
    federated: {
      id: email,
      name: 'Max Mustermann',
      provider: 'https://accounts.google.com'
    },
    signal: controller.signal
  });
  await navigator.credentials.store(cred);
  return cred.provider;
};

saveFederated('max@example.com').then(console.log);
https://accounts.google.com

Doppelte Registrierung verhindern

const createUnique = async (publicKeyOptions, existingIds) => {
  try {
    return await navigator.credentials.create({
      publicKey: {
        ...publicKeyOptions,
        // bereits registrierte Authenticatoren ausschließen
        excludeCredentials: existingIds.map((id) => ({ type: 'public-key', id }))
      }
    });
  } catch (err) {
    if (err.name === 'InvalidStateError') {
      console.warn('Dieses Gerät ist bereits registriert.');
    } else if (err.name === 'NotAllowedError') {
      console.warn('Vorgang abgebrochen oder Zeit abgelaufen.');
    } else {
      throw err;
    }
    return null;
  }
};