API-Überblick
Eine API für alle Kanäle. Was die Webseite nutzt, nutzen auch die Apps — es gibt keine zweite Berechtigungslogik, die auseinanderlaufen könnte.
Zwei Wege hinein, ein Ergebnis
Jede Anfrage wird über genau einen von zwei Wegen authentifiziert. Beide münden serverseitig in denselben Typ; die Fachlogik dahinter kennt den Unterschied nicht.
- Browser
- Opakes
__Host--Cookie. Zustandsändernde Anfragen zusätzlich mitX-CSRF-TokenausGET /api/v1/session. - Native App
Authorization: DPoP <token>plusDPoP-Proof je Anfrage (RFC 9449). Kein CSRF-Token nötig — es wird kein Cookie automatisch mitgesendet.
Einstieg für eine App
Client-ID, Endpunkte und Scopes werden nicht in der App fest verdrahtet, sondern zur Laufzeit geholt. Damit lässt sich die Konfiguration ändern, ohne auf ein App-Store-Release zu warten:
GET /api/v1/mobile/configDie Antwort enthält unter anderem:
issuer,authorizationEndpoint,tokenEndpoint,endSessionEndpointclientId,audience,scopespkce(immer erforderlich, MethodeS256)dpop(Pflicht, erlaubte Verfahren, maximales Alter eines Proofs)
Endpunkte
| Methode & Pfad | Zweck |
|---|---|
GET /auth/login | Startet die Anmeldung, leitet zum Identity Provider weiter |
GET /auth/register | Startet die Registrierung |
GET /auth/step-up | Erhöht die Vertrauensstufe einer laufenden Sitzung |
POST /auth/logout | Beendet die Sitzung lokal und beim Provider |
GET /api/v1/session | Sitzungsstatus und CSRF-Token |
GET /api/v1/sessions | Aktive Sitzungen des Kontos |
DELETE /api/v1/sessions/:id | Einzelne Sitzung beenden |
GET /api/v1/account/profile | Profil und Verweise auf die Zugangsdatenverwaltung |
GET /api/v1/account/export | Datenauskunft nach Art. 15/20 DSGVO |
POST /api/v1/mobile/devices | Gerät der App registrieren |
GET /api/v1/openapi.json | Maschinenlesbare Beschreibung aller Endpunkte |
Fehler
Fehler kommen als JSON mit einem stabilen, maschinenlesbaren Code und einer requestId zurück — nie mit einer Innenansicht des Systems. Die Ursache steht ausschließlich im Serverprotokoll.
| Code | Status | Bedeutung |
|---|---|---|
authentication_required | 401 | Keine gültige Sitzung beziehungsweise kein gültiges Token |
step_up_required | 403 | Höhere Vertrauensstufe nötig; Ziel steht in der Antwort |
reauthentication_required | 403 | Anmeldung zu alt für diesen Schritt |
csrf_validation_failed | 403 | Herkunft oder CSRF-Token nicht akzeptiert |
dpop_proof_invalid | 401 | Proof fehlt, passt nicht oder wurde wiederverwendet |
use_dpop_nonce | 401 | Server-Nonce erforderlich; sie steht im Header DPoP-Nonce und gehört in den nächsten Proof |
rate_limit_exceeded | 429 | Begrenzung erreicht; Retry-After beachten |
Eine eigene Funktion ergänzen
Der Dienst ist als Modulkern gebaut. Ein neuer Bereich ist ein Ordner unter src/modules/, der ein Modul exportiert, plus ein Eintrag in modules/index.ts. Kein bestehender Handler wird angefasst, keine zentrale Routendatei wächst mit. Abhängigkeiten zwischen Modulen werden deklariert und beim Start topologisch sortiert; ein Zyklus bricht den Start ab, statt sich später als schwer auffindbarer Reihenfolgefehler zu zeigen.