Autenticación y seguridad
La API utiliza una combinación de autenticación basada en sesiones y protección CSRF para todas las operaciones de escritura en la base de datos a fin de evitar accesos no autorizados y posibles ataques de denegación de servicio. Las APIs externas utilizadas por Duplicati y Homepage permanecen exentas de CSRF. De forma opcional, pueden requerir una clave de API con ámbito y/o una lista de IPs permitidas (ambas desactivadas de forma predeterminada). /api/upload también tiene un límite de tamaño de cuerpo configurable y un límite de tasa.
Autenticación basada en sesiones
Los endpoints protegidos requieren una cookie de sesión válida y un token CSRF. El sistema de sesiones proporciona una autenticación segura para todas las operaciones protegidas.
Gestión de sesiones
- Crear sesión: POST a
/api/sessionpara crear una nueva sesión - Obtener token CSRF: GET
/api/csrfpara obtener un token CSRF para la sesión - Incluir en las solicitudes: Envíe la cookie de sesión y el token CSRF con las solicitudes protegidas
- Validar sesión: GET
/api/sessionpara comprobar si la sesión sigue siendo válida - Eliminar sesión: DELETE
/api/sessionpara cerrar sesión y borrar la sesión
Protección CSRF
Todas las operaciones que modifican el estado requieren un token CSRF válido que coincida con la sesión actual. El token CSRF debe incluirse en el encabezado X-CSRF-Token para los endpoints protegidos.
Endpoints protegidos
Todos los endpoints que modifican datos de la base de datos requieren autenticación de sesión y token CSRF:
- Gestión del servidor:
/api/servers/:id(PATCH, DELETE),/api/servers/:id/server-url(PATCH),/api/servers/:id/password(PATCH, GET) - Gestión de configuración:
/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),/api/configuration/daily-summary(GET, POST),/api/configuration/daily-summary/send(POST),/api/configuration/daily-summary/retry(POST),/api/configuration/daily-summary/preview(POST) - Sistema de notificaciones:
/api/notifications/test(POST),/api/notifications/preview(POST),/api/notification-channel-alerts(GET, POST) - se requiere administrador; POST también requiere un token CSRF - Configuración de Cron:
/api/cron-config(GET, POST) - Proxy de Cron:
/api/cron/*(GET, POST): redirige solicitudes al servicio cron. POST requiere un administrador. El proceso cron se vincula a127.0.0.1de forma predeterminada; las rutas mutables del servicio cron requierenX-Cron-Service-SecretcuandoCRON_SERVICE_SECRETestá configurado. - Gestión de sesiones:
/api/session(POST, GET, DELETE),/api/csrf(GET) - Datos de gráficos:
/api/chart-data/*(GET) - Panel de control:
/api/dashboard(GET) - Detalles del servidor:
/api/servers(GET),/api/servers/:id(GET),/api/detail/:serverId(GET) - Registro de auditoría:
/api/audit-log(GET),/api/audit-log/download(GET),/api/audit-log/filters(GET),/api/audit-log/retention(PATCH),/api/audit-log/cleanup(POST): se requiere administrador para operaciones de escritura - Gestión de usuarios:
/api/users(GET, POST, PATCH, DELETE): se requiere administrador - Gestión de la base de datos:
/api/database/backup(GET),/api/database/restore(POST): se requiere administrador - Registros de la Aplicación:
/api/application-logs(GET),/api/application-logs/export(GET): se requiere administrador - Recopilación de copias de seguridad:
/api/backups/collect(POST): requiere sesión y token CSRF - Sincronización de programación de copias de seguridad:
/api/backups/sync-schedule(POST): requiere sesión y token CSRF - Comprobación de vencimiento:
/api/notifications/check-overdue(POST): requiere sesión y token CSRF - Borrar marcas de tiempo de vencimiento:
/api/notifications/clear-overdue-timestamps(POST): requiere sesión y token CSRF
Endpoints externos
Estas rutas no utilizan cookies de sesión ni CSRF. La autenticación es opcional y se configura en Configuración:
/api/upload- Subidas de datos de copias de seguridad desde Duplicati (clave de ámbito upload, límites de tamaño y tasa)/api/lastbackup/:serverId- Estado de la copia de seguridad más reciente (clave de ámbito read)/api/lastbackups/:serverId- Estado de las copias de seguridad más recientes (clave de ámbito read)/api/summary- Datos de resumen general (clave de ámbito read)/api/health- Endpoint de comprobación de estado de salud (nunca con clave; sondeo ligero de SQLite; límite de tasa por IP)/api/ping- Sondeo de conectividad (nunca con clave; límite de tasa por IP)
Cuando Require API keys está desactivado, las cuatro primeras rutas aceptan solicitudes con o sin clave: se registra una clave válida con ámbito coincidente; se ignora una clave incorrecta. Cuando el interruptor está activado, devuelven 401 sin una clave válida y 403 cuando el ámbito de la clave no coincide. /api/health e /api/ping nunca usan claves. Consulte Claves de API y Lista de IPs permitidas.
Ejemplo de uso (sesión + 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'
})
});
Endpoints de autenticación
Inicio de sesión - /api/auth/login
-
Punto de conexión:
/api/auth/login -
Método: POST
-
Descripción: Autentica un usuario y crea una sesión. Admite bloqueo de cuenta después de intentos fallidos y requisitos de cambio de contraseña.
-
Autenticación: Requiere sesión válida y token CSRF (pero sin usuario conectado)
-
Cuerpo de la solicitud:
{"username": "admin","password": "password123"} -
Respuesta (éxito):
{"success": true,"user": {"id": "user-id","username": "admin","isAdmin": true,"mustChangePassword": false},"keyChanged": false} -
Respuestas de Error: Todas las respuestas de error incluyen
error(mensaje en inglés) yerrorCode(código estable para traducción del lado del cliente).400: Falta nombre de usuario o contraseña —errorCode: "REQUIRED_CREDENTIALS"401: Nombre de usuario o contraseña no válidos —errorCode: "INVALID_CREDENTIALS"403: Cuenta bloqueada debido a demasiados intentos de inicio de sesión fallidos —errorCode: "ACCOUNT_LOCKED"(incluyelockedUntil,minutesRemaining)500: Error interno del servidor —errorCode: "INTERNAL_ERROR"503: Base de datos no está lista —errorCode: "DATABASE_NOT_READY"
-
Notas:
- La cuenta se bloquea después de 5 intentos de inicio de sesión fallidos durante 15 minutos
- Los intentos de inicio de sesión fallidos se rastrean y registran
- La cookie de sesión se establece automáticamente en la respuesta
- Si el usuario tiene la bandera
mustChangePasswordactivada, se debe redirigir al usuario a la página de cambio de contraseña - Todos los intentos de inicio de sesión (exitosos y fallidos) se registran en el registro de auditoría
Cerrar sesión - /api/auth/logout
-
Punto de conexión:
/api/auth/logout -
Método: POST
-
Descripción: Cierra la sesión del usuario actual y destruye su sesión.
-
Autenticación: Requiere sesión válida y token CSRF
-
Respuesta (éxito):
{"success": true,"message": "Logged out successfully","successCode": "LOGGED_OUT"} -
Respuestas de Error: Incluye
erroryerrorCodepara traducción del lado del cliente.400: No hay sesión activa —errorCode: "NO_ACTIVE_SESSION"500: Error interno del servidor —errorCode: "INTERNAL_ERROR"
-
Notas:
- La cookie de sesión se borra en la respuesta
- El cierre de sesión se registra en el registro de auditoría
- La sesión se invalida inmediatamente
Obtener usuario actual - /api/auth/me
-
Punto de conexión:
/api/auth/me -
Método: GET
-
Descripción: Devuelve la información del usuario autenticado actual, o indica si no hay ningún usuario conectado.
-
Autenticación: Requiere sesión válida (pero no se requiere usuario conectado)
-
Respuesta (autenticado):
{"authenticated": true,"user": {"id": "user-id","username": "admin","isAdmin": true,"mustChangePassword": false}} -
Respuesta (no autenticado):
{"authenticated": false,"user": null} -
Respuestas de Error: Incluye
erroryerrorCodepara traducción del lado del cliente.500: Error interno del servidor —errorCode: "INTERNAL_ERROR"
-
Notas:
- Se puede llamar sin un usuario conectado (devuelve
authenticated: false) - Útil para comprobar el estado de autenticación al cargar la página
- Se puede llamar sin un usuario conectado (devuelve
Cambiar contraseña - /api/auth/change-password
-
Punto de conexión:
/api/auth/change-password -
Método: POST
-
Descripción: Cambia la contraseña del usuario autenticado actual. Si
mustChangePasswordestá establecido, se omite la verificación de contraseña actual. -
Autenticación: Requiere sesión válida y token CSRF (usuario conectado requerido)
-
Cuerpo de la solicitud:
{"currentPassword": "old-password","newPassword": "new-secure-password"} -
currentPassword: Opcional simustChangePasswordes verdadero, requerido de lo contrarionewPassword: Requerido, debe cumplir con los requisitos de la política de contraseñas
-
Respuesta (éxito):
{"success": true,"message": "Password changed successfully","successCode": "PASSWORD_CHANGED"} -
Respuestas de Error: Incluye
erroryerrorCodepara traducción del lado del cliente. La violación de política puede incluirvalidationErrors(matriz de cadenas).400: Falta la nueva contraseña —errorCode: "NEW_PASSWORD_REQUIRED"400: Violación de la política de contraseñas —errorCode: "POLICY_NOT_MET"(puede incluirvalidationErrors)400: Nueva contraseña igual que la actual —errorCode: "NEW_PASSWORD_SAME_AS_CURRENT"401: La contraseña actual es incorrecta —errorCode: "CURRENT_PASSWORD_INCORRECT"404: Usuario no encontrado —errorCode: "USER_NOT_FOUND"500: Error interno del servidor —errorCode: "INTERNAL_ERROR"
-
Notas:
- La nueva contraseña debe cumplir con los requisitos de la política de contraseñas (longitud, complejidad, etc.)
- Si la bandera
mustChangePasswordestá activada, se omite la verificación de la contraseña actual - Después de un cambio de contraseña exitoso, la bandera
mustChangePasswordse desactiva - Los cambios de contraseña se registran en el registro de auditoría
- La nueva contraseña debe ser diferente de la contraseña actual
Comprobar Debe cambiar la contraseña de Administrador - /api/auth/admin-must-change-password
-
Endpoint:
/api/auth/admin-must-change-password -
Método: GET
-
Descripción: Comprueba si el usuario administrador debe cambiar su contraseña. Este endpoint es público (no requiere autenticación), ya que solo devuelve un indicador booleano.
-
Respuesta:
{"mustChangePassword": false} -
Respuestas de Error:
500: Error interno del servidor (devuelvemustChangePassword: falseen caso de error para evitar mostrar el mensaje si hay un problema de base de datos)
-
Notas:
- Punto final público, no se requiere autenticación
- Devuelve
falsesi no existe el usuario administrador - Se utiliza para determinar si se debe mostrar el mensaje de cambio de contraseña
- En caso de error, devuelve
falsepara evitar mostrar el mensaje si hay un problema de base de datos
Obtener directiva de contraseñas - /api/auth/password-policy
-
Endpoint:
/api/auth/password-policy -
Método: GET
-
Descripción: Devuelve la configuración de la directiva de contraseñas actual. Este endpoint es público (no requiere autenticación), ya que es necesario para la validación en el frontend.
-
Respuesta:
{"minLength": 8,"requireUppercase": true,"requireLowercase": true,"requireNumbers": true,"requireSpecialChars": false} -
Respuestas de Error: Incluye
erroryerrorCodepara traducción del lado del cliente.500: Error al recuperar la política de contraseñas —errorCode: "POLICY_RETRIEVE_FAILED"
-
Notas:
- Punto final público, no se requiere autenticación
- Utilizado por componentes del frontend para mostrar los requisitos de contraseña y validar contraseñas antes del envío
- La política se configura mediante variables de entorno (
PWD_ENFORCE,PWD_MIN_LEN) - La verificación predeterminada de contraseña (para evitar el uso de la contraseña predeterminada de administrador) siempre se aplica independientemente de la configuración de la política
Códigos de error y de éxito de la API de autenticación (i18n)
Los endpoints de autenticación devuelven un errorCode estable (y, en caso de éxito, successCode) además del campo legible para personas error o message. Los valores de error e message están en inglés. Los clientes deben utilizar los códigos para buscar las cadenas localizadas de modo que la interfaz de usuario muestre los mensajes en el idioma seleccionado por el usuario.
| Endpoint | Código de éxito | Códigos de error |
|---|---|---|
/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 |
Respuestas de error
401 Unauthorized: Sesión no válida o ausente, sesión expirada o fallo en la validación del token CSRF403 Forbidden: Fallo en la validación del token CSRF u operación no permitida
No exponga el servidor de duplistatus a la red pública de internet. Utilícelo en una red segura (p. ej., una LAN local protegida por un cortafuegos).
Exponer la interfaz de duplistatus a la red pública de internet sin las medidas de seguridad adecuadas podría provocar accesos no autorizados.