Passkeys

auth.webauthn

WebAuthn-Modul (Passkeys, Fingerabdruck, Face ID, Hardware-Key). Unabhängig vom CMS.

Einbindung in server.ts

ts
app.modules.add(import.meta.resolve("../qino/module/auth.webauthn/plugin.ts"));

// Optional:
app.modules.add(import.meta.resolve("../qino/module/cms.cont.login.webauthn/plugin.ts"));
app.modules.add(import.meta.resolve("../qino/module/cms.backend.superuser.security.auth.webauthn/plugin.ts"));

Settings

Key Default Beschreibung
rpId Host von core.url ohne www., sonst "localhost" Domain ohne Protokoll, z.B. example.com

Akzeptiert wird die Origin des Requests, wenn ihr Host unter der rpId liegt oder ein Host der App ist (core.hosts und der Host von core.url). Diese Hosts dürfen Passkeys der rpId mitbenutzen (/.well-known/webauthn, Related Origins) — so bleiben Passkeys auch nach einem Domainwechsel gültig, solange die alte Domain als rpId gesetzt ist und weiter auf die App zeigt.

API

Basis: {appUrl}api/auth.webauthn/

Methode Pfad Auth Beschreibung
POST register/challenge USER Challenge für Registrierung
POST register/verify USER Credential speichern
POST login/challenge PUBLIC Challenge für Login
POST login/verify PUBLIC Login verifizieren → Session
GET credentials USER Eigene Credentials auflisten
DELETE credential/:id USER Credential löschen
POST confirm/challenge USER Step-up Challenge anfordern
POST confirm/verify USER Step-up bestätigen → Session-Flag

Client

js
import { WebAuthn } from "/m/auth.webauthn/pub/webauthn.js";

const wa = new WebAuthn({ apiBase: "/cms1/api/auth.webauthn" });
await wa.register({ name: "Mein MacBook" });
await wa.login();
await wa.loginConditional(); // Autofill-Passkey (Conditional UI), null wenn nicht verfügbar

Fertige UI liefern die Content-Module cms.cont.login.webauthn (anmelden) und cms.cont.my.webauthn (eigene Passkeys verwalten) — siehe unten.

Step-up Authentication

js
const r = await wa.confirm(); // öffnet Authenticator-Dialog
if (r.ok) { /* geschützte Aktion */ }

Der Nachweis landet über auth in der Session. Serverseitig verlangt ihn requireStepUp am api-Verb oder im guard — für jeden Faktor, nicht nur Passkeys (siehe auth).

CMS-Module

cms.cont.login.webauthn — Content-Node zum Anmelden, Settings:

Setting Beschreibung
apiBase URL der API (Standard: aus App-Pfad abgeleitet)
redirectAfterLogin Page-ID für Weiterleitung nach Login

cms.cont.my.webauthn — Content-Node, auf dem der angemeldete Benutzer seine eigenen Passkeys verwaltet. Ohne Settings.

cms.backend.superuser.security.auth.webauthn — Backend-Seite, listet alle Credentials (Superuser).