Authentifizierung & Sicherheit
Die API verwendet eine Kombination aus sessionbasierter Authentifizierung und CSRF-Schutz für alle Datenbankschreibvorgänge, um unbefugten Zugriff und mögliche Denial-of-Service-Angriffe zu verhindern. Externe APIs (verwendet von Duplicati) bleiben aus Kompatibilitätsgründen nicht authentifiziert.
Sessionbasierte Authentifizierung
Geschützte Endpunkte erfordern ein gültiges Sitzungs-Cookie und einen CSRF-Token. Das Sitzungssystem bietet eine sichere Authentifizierung für alle geschützten Operationen.
Sitzungsverwaltung
- Sitzung erstellen: POST-Anfrage an
/api/session, um eine neue Sitzung zu erstellen - CSRF-Token abrufen: GET-Anfrage an
/api/csrf, um ein CSRF-Token für die Sitzung zu erhalten - In Anfragen einbinden: Sitzungs-Cookie und CSRF-Token mit geschützten Anfragen senden
- Sitzung prüfen: GET
/api/session, um zu überprüfen, ob die Sitzung noch gültig ist - Sitzung löschen: DELETE
/api/session, um sich abzumelden und die Sitzung zu löschen
CSRF-Schutz
Alle statusändernden Operationen erfordern einen gültigen CSRF-Token, der mit der aktuellen Sitzung übereinstimmt. Der CSRF-Token muss im X-CSRF-Token-Header für geschützte Endpunkte enthalten sein.
Geschützte Endpunkte
Alle Endpunkte, die Datenbankdaten ändern, erfordern eine Sitzungsauthentifizierung und einen CSRF-Token:
- Serververwaltung:
/api/servers/:id(PATCH, DELETE),/api/servers/:id/server-url(PATCH),/api/servers/:id/password(PATCH, GET) - Konfigurationsverwaltung:
/api/configuration/email(GET, POST, DELETE),/api/configuration/unified(GET),/api/configuration/ntfy(GET),/api/configuration/notifications(GET, POST),/api/configuration/backup-settings(POST),/api/configuration/templates(POST),/api/configuration/overdue-tolerance(GET, POST) - Benachrichtigungssystem:
/api/notifications/test(POST) - Cron-Konfiguration:
/api/cron-config(GET, POST) - Cron-Proxy:
/api/cron/*(GET, POST) – leitet Anfragen an den Cron-Dienst weiter - Sitzungsverwaltung:
/api/session(POST, GET, DELETE),/api/csrf(GET) - Diagrammdaten:
/api/chart-data/*(GET) - Dashboard:
/api/dashboard(GET) - Serverdetails:
/api/servers(GET),/api/servers/:id(GET),/api/detail/:serverId(GET) - Audit-Log:
/api/audit-log(GET),/api/audit-log/download(GET),/api/audit-log/filters(GET),/api/audit-log/retention(PATCH),/api/audit-log/cleanup(POST) – Administrator erforderlich für Schreibvorgänge - Benutzerverwaltung:
/api/users(GET, POST, PATCH, DELETE) – Administrator erforderlich - Datenbankverwaltung:
/api/database/backup(GET),/api/database/restore(POST) – Administrator erforderlich - Anwendungsprotokolle:
/api/application-logs(GET),/api/application-logs/export(GET) – Administrator erforderlich - Backup-Sammlung:
/api/backups/collect(POST) – erfordert Sitzung und CSRF-Token - Backup-Zeitplan-Synchronisierung:
/api/backups/sync-schedule(POST) – erfordert Sitzung und CSRF-Token - Überfälligkeitsprüfung:
/api/notifications/check-overdue(POST) – erfordert Sitzung und CSRF-Token - Überfällige Zeitstempel löschen:
/api/notifications/clear-overdue-timestamps(POST) – erfordert Sitzung und CSRF-Token
Ungeschützte Endpunkte
Externe APIs bleiben für die Duplicati-Integration nicht authentifiziert:
/api/upload– Upload von Backup-Daten aus Duplicati/api/lastbackup/:serverId– Aktueller Backup-Status/api/lastbackups/:serverId– Status der letzten Backups/api/summary– Gesamte Zusammenfassungsdaten/api/health– Health-Check-Endpunkt
Verwendungsbeispiel (Sitzung + CSRF)
// 1. Create session
const sessionResponse = await fetch('/api/session', { method: 'POST' });
const { sessionId } = await sessionResponse.json();
// 2. Get CSRF token
const csrfResponse = await fetch('/api/csrf', {
headers: { 'Cookie': `session=${sessionId}` }
});
const { csrfToken } = await csrfResponse.json();
// 3. Make protected request
const response = await fetch('/api/servers/server-id', {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
'X-CSRF-Token': csrfToken,
'Cookie': `session=${sessionId}`
},
body: JSON.stringify({
alias: 'Updated Server Name',
note: 'Updated notes'
})
});
Authentifizierungs-Endpunkte
Anmeldung - /api/auth/login
-
Endpunkt:
/api/auth/login -
Methode: POST
-
Beschreibung: Authentifiziert einen Benutzer und erstellt eine Sitzung. Unterstützt Sperrung des Kontos nach fehlgeschlagenen Versuchen und Passwortänderungsanforderungen.
-
Authentifizierung: Erfordert gültige Sitzung und CSRF-Token (aber keinen angemeldeten Benutzer)
-
Anfrage-Body:
{"username": "admin","password": "password123"} -
Antwort (Erfolg):
{"success": true,"user": {"id": "user-id","username": "admin","isAdmin": true,"mustChangePassword": false},"keyChanged": false} -
Fehlerantworten: Alle Fehlerantworten enthalten
error(Nachricht in Englisch) underrorCode(stabilen Code für clientseitige Übersetzung).400: Benutzername oder Passwort fehlt —errorCode: "REQUIRED_CREDENTIALS"401: Ungültiger Benutzername oder Passwort —errorCode: "INVALID_CREDENTIALS"403: Konto gesperrt aufgrund zu vieler fehlgeschlagener Anmeldeversuche —errorCode: "ACCOUNT_LOCKED"(enthältlockedUntil,minutesRemaining)500: Interner Serverfehler —errorCode: "INTERNAL_ERROR"503: Datenbank nicht bereit —errorCode: "DATABASE_NOT_READY"
-
Hinweise:
- Das Konto wird nach 5 fehlgeschlagenen Anmeldeversuchen für 15 Minuten gesperrt
- Fehlgeschlagene Anmeldeversuche werden verfolgt und protokolliert
- Das Sitzungs-Cookie wird automatisch in der Antwort gesetzt
- Wenn das
mustChangePassword-Flag beim Benutzer gesetzt ist, sollte er zur Passwortänderungsseite weitergeleitet werden - Alle Anmeldeversuche (erfolgreich und fehlgeschlagen) werden im Audit-Log protokolliert
Abmeldung - /api/auth/logout
-
Endpunkt:
/api/auth/logout -
Methode: POST
-
Beschreibung: Meldet den aktuellen Benutzer ab und löscht dessen Sitzung.
-
Authentifizierung: Erfordert gültige Sitzung und CSRF-Token
-
Antwort (Erfolg):
{"success": true,"message": "Logged out successfully","successCode": "LOGGED_OUT"} -
Fehlerantworten: Enthalten
errorunderrorCodezur clientseitigen Übersetzung.400: Keine aktive Sitzung —errorCode: "NO_ACTIVE_SESSION"500: Interner Serverfehler —errorCode: "INTERNAL_ERROR"
-
Hinweise:
- Das Sitzungs-Cookie wird in der Antwort gelöscht
- Die Abmeldung wird im Audit-Log protokolliert
- Die Sitzung wird sofort ungültig gemacht
Aktuellen Benutzer abrufen - /api/auth/me
-
Endpunkt:
/api/auth/me -
Methode: GET
-
Beschreibung: Gibt die Informationen des aktuell authentifizierten Benutzers zurück oder zeigt an, wenn kein Benutzer angemeldet ist.
-
Authentifizierung: Erfordert gültige Sitzung (kein angemeldeter Benutzer erforderlich)
-
Antwort (authentifiziert):
{"authenticated": true,"user": {"id": "user-id","username": "admin","isAdmin": true,"mustChangePassword": false}} -
Antwort (nicht authentifiziert):
{"authenticated": false,"user": null} -
Fehlerantworten: Enthalten
errorunderrorCodezur clientseitigen Übersetzung.500: Interner Serverfehler —errorCode: "INTERNAL_ERROR"
-
Hinweise:
- Kann ohne angemeldeten Benutzer aufgerufen werden (gibt
authenticated: falsezurück) - Nützlich zur Überprüfung des Authentifizierungsstatus beim Laden der Seite
- Kann ohne angemeldeten Benutzer aufgerufen werden (gibt
Passwort ändern - /api/auth/change-password
-
Endpunkt:
/api/auth/change-password -
Methode: POST
-
Beschreibung: Ändert das Passwort für den aktuell authentifizierten Benutzer. Wenn
mustChangePasswordgesetzt ist, entfällt die Überprüfung des aktuellen Passworts. -
Authentifizierung: Erfordert gültige Sitzung und CSRF-Token (angemeldeter Benutzer erforderlich)
-
Anforderungstext:
{"currentPassword": "old-password","newPassword": "new-secure-password"} -
currentPassword: Optional, wennmustChangePasswordwahr ist, andernfalls erforderlichnewPassword: Erforderlich, muss die Passwortrichtlinie erfüllen
-
Antwort (Erfolg):
{"success": true,"message": "Password changed successfully","successCode": "PASSWORD_CHANGED"} -
Fehlerantworten: Enthalten
errorunderrorCodezur clientseitigen Übersetzung. Bei Verstoß gegen die Richtlinie kannvalidationErrorsenthalten sein (Array von Zeichenketten).400: Neues Passwort fehlt —errorCode: "NEW_PASSWORD_REQUIRED"400: Verstoß gegen die Passwortrichtlinie —errorCode: "POLICY_NOT_MET"(kannvalidationErrorsenthalten)400: Neues Passwort entspricht aktuellem Passwort —errorCode: "NEW_PASSWORD_SAME_AS_CURRENT"401: Aktuelles Passwort ist falsch —errorCode: "CURRENT_PASSWORD_INCORRECT"404: Benutzer nicht gefunden —errorCode: "USER_NOT_FOUND"500: Interner Serverfehler —errorCode: "INTERNAL_ERROR"
-
Hinweise:
- Das neue Passwort muss die Anforderungen der Passwortrichtlinie erfüllen (Länge, Komplexität usw.)
- Wenn das
mustChangePassword-Flag gesetzt ist, entfällt die Überprüfung des aktuellen Passworts - Nach erfolgreicher Passwortänderung wird das
mustChangePassword-Flag gelöscht - Passwortänderungen werden im Audit-Log protokolliert
- Neues Passwort muss sich vom aktuellen Passwort unterscheiden
Überprüfen, ob Administrator Passwort ändern muss - /api/auth/admin-must-change-password
-
Endpunkt:
/api/auth/admin-must-change-password -
Methode: GET
-
Beschreibung: Überprüft, ob der Admin-Benutzer sein Passwort ändern muss. Dieser Endpunkt ist öffentlich (keine Authentifizierung erforderlich), da er lediglich eine boolesche Kennung zurückgibt.
-
Antwort:
{"mustChangePassword": false} -
Fehlerantworten:
500: Interner Serverfehler (gibt bei FehlernmustChangePassword: falsezurück, um den Hinweis nicht anzuzeigen, falls ein Datenbankproblem vorliegt)
-
Hinweise:
- Öffentlicher Endpunkt, keine Authentifizierung erforderlich
- Gibt
falsezurück, wenn der Admin-Benutzer nicht existiert - Wird verwendet, um zu bestimmen, ob der Hinweis zur Passwortänderung angezeigt werden soll
- Bei Fehlern gibt er
falsezurück, um den Hinweis nicht anzuzeigen, falls ein Datenbankproblem vorliegt
Passwortsicherheitsrichtlinie abrufen - /api/auth/password-policy
-
Endpunkt:
/api/auth/password-policy -
Methode: GET
-
Beschreibung: Gibt die aktuelle Konfiguration der Passwortsicherheitsrichtlinie zurück. Dieser Endpunkt ist öffentlich (keine Authentifizierung erforderlich), da er für die Frontend-Validierung benötigt wird.
-
Antwort:
{"minLength": 8,"requireUppercase": true,"requireLowercase": true,"requireNumbers": true,"requireSpecialChars": false} -
Fehlerantworten: Enthalten
errorunderrorCodezur clientseitigen Übersetzung.500: Abrufen der Passwortrichtlinie fehlgeschlagen —errorCode: "POLICY_RETRIEVE_FAILED"
-
Hinweise:
- Öffentlicher Endpunkt, keine Authentifizierung erforderlich
- Wird von Frontend-Komponenten verwendet, um Passwortanforderungen anzuzeigen und Passwörter vor der Übergabe zu überprüfen
- Die Richtlinie wird über Umgebungsvariablen konfiguriert (
PWD_ENFORCE,PWD_MIN_LEN) - Die Standardpasswortprüfung (um die Verwendung des Standard-Administratorpassworts zu verhindern) wird immer unabhängig von den Richtlinieneinstellungen erzwungen
Auth-API-Fehler- und Erfolgscodes (i18n)
Auth-Endpunkte geben einen stabilen errorCode (und bei Erfolg successCode) zusätzlich zum menschenlesbaren Feld error oder message zurück. Die Werte von error und message sind in Englisch. Clients sollten die Codes verwenden, um lokalisierte Zeichenketten nachzuschlagen, sodass die Benutzeroberfläche Nachrichten in der vom Benutzer gewählten Sprache anzeigt.
| Endpunkt | Erfolgscode | Fehlercodes |
|---|---|---|
/api/auth/login | — | REQUIRED_CREDENTIALS, INVALID_CREDENTIALS, ACCOUNT_LOCKED, DATABASE_NOT_READY, INTERNAL_ERROR |
/api/auth/logout | LOGGED_OUT | NO_ACTIVE_SESSION, INTERNAL_ERROR |
/api/auth/me | — | INTERNAL_ERROR |
/api/auth/change-password | PASSWORD_CHANGED | NEW_PASSWORD_REQUIRED, POLICY_NOT_MET, USER_NOT_FOUND, CURRENT_PASSWORD_INCORRECT, NEW_PASSWORD_SAME_AS_CURRENT, INTERNAL_ERROR |
/api/auth/password-policy | — | POLICY_RETRIEVE_FAILED |
Fehlerantworten
401 Unauthorized: Ungültige oder fehlende Sitzung, abgelaufene Sitzung oder fehlgeschlagene CSRF-Token-Validierung403 Forbidden: CSRF-Token-Validierung fehlgeschlagen oder Operation nicht erlaubt
Stellen Sie den duplistatus-Server nicht dem öffentlichen Internet zur Verfügung. Nutzen Sie ihn in einem sicheren Netzwerk (z. B. lokales LAN, geschützt durch eine Firewall).
Die Bereitstellung der duplistatus-Schnittstelle im öffentlichen Internet ohne angemessene Sicherheitsmaßnahmen könnte zu unbefugtem Zugriff führen.