Autenticación
NoxPanel utiliza JSON Web Tokens (JWT) como mecanismo principal de autenticación
para la API REST. Los tokens son emitidos por django-rest-framework-simplejwt.
Obtener Tokens JWT
Endpoint: Login
POST /accounts/api/login/
Solicita un par de tokens (access + refresh) proporcionando credenciales de usuario.
Request body:
{
"username": "admin",
"password": "mi_password_seguro"
}
Respuesta exitosa (200):
{
"access": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNzA5MjM0NTY3LCJ1c2VyX2lkIjoxfQ.abc123...",
"refresh": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoicmVmcmVzaCIsImV4cCI6MTcwOTgzMjE2NywidXNlcl9pZCI6MX0.def456..."
}
Ejemplo con curl:
curl -X POST https://panel.example.com/accounts/api/login/ \
-H "Content-Type: application/json" \
-d '{"username": "admin", "password": "mi_password_seguro"}'
Respuesta de error (401):
{
"detail": "No se encontró una cuenta activa con las credenciales proporcionadas."
}
Refrescar Token
Endpoint: Token Refresh
POST /accounts/api/token/refresh/
Obtiene un nuevo access token usando el refresh token vigente. Tras la rotación, el refresh token anterior queda invalidado.
Request body:
{
"refresh": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."
}
Respuesta exitosa (200):
{
"access": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.nuevo_access_token...",
"refresh": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.nuevo_refresh_token..."
}
Ejemplo con curl:
curl -X POST https://panel.example.com/accounts/api/token/refresh/ \
-H "Content-Type: application/json" \
-d '{"refresh": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."}'
Usar el Token en Peticiones
Una vez obtenido el access token, inclúyelo en la cabecera Authorization
de todas las peticiones posteriores:
Authorization: Bearer <access_token>
Ejemplo completo — listar sitios web:
# 1. Obtener token
TOKEN=$(curl -s -X POST https://panel.example.com/accounts/api/login/ \
-H "Content-Type: application/json" \
-d '{"username": "admin", "password": "mi_password"}' \
| python3 -c "import sys, json; print(json.load(sys.stdin)['access'])")
# 2. Usar token para listar sitios
curl -X GET https://panel.example.com/hosting/api/rest/sites/ \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json"
Ejemplo — crear un sitio web:
curl -X POST https://panel.example.com/hosting/api/rest/sites/ \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"domain": "nuevo-sitio.com", "ip_address": "*"}'
Configuración del JWT
Parámetro |
Valor |
Descripción |
|---|---|---|
Access Token Lifetime |
60 minutos |
Tiempo de vida del token de acceso |
Refresh Token Lifetime |
7 días |
Tiempo de vida del token de refresco |
Algoritmo |
HS256 |
Algoritmo de firma |
Rotación de Refresh |
Sí |
Se genera nuevo refresh al refrescar |
Blacklist tras Rotación |
Sí |
El refresh anterior queda invalidado |
Tipo de Cabecera |
Bearer |
Prefijo en Authorization header |
Autenticación por Sesión (Panel Web)
El panel web de NoxPanel usa autenticación por sesión Django. Las peticiones AJAX
desde el navegador envían automáticamente la cookie sessionid y el token CSRF.
Para peticiones desde JavaScript en el navegador:
// Leer CSRF token de la cookie
function getCookie(name) {
let value = `; ${document.cookie}`;
let parts = value.split(`; ${name}=`);
if (parts.length === 2) return parts.pop().split(';').shift();
}
// Petición con sesión + CSRF
fetch('/hosting/api/rest/sites/', {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': getCookie('csrftoken'),
},
credentials: 'same-origin',
});
Manejo de Errores de Autenticación
Código |
Causa |
Solución |
|---|---|---|
|
Token expirado o inválido |
Refrescar el token o hacer login de nuevo |
|
Token no proporcionado |
Añadir cabecera |
|
Refresh token expirado |
Realizar login completo de nuevo |
|
Usuario sin permisos para el recurso |
Verificar rol y acceso al módulo |
Buenas Prácticas
Almacena tokens de forma segura: Nunca expongas tokens en URLs o logs.
Refresca proactivamente: Refresca el access token antes de que expire.
Maneja la expiración: Si recibes un
401, intenta refrescar antes de redirigir al login.Usa HTTPS: Todas las peticiones deben ir sobre HTTPS en producción.
No compartas tokens: Cada integración debe tener su propio usuario y credenciales.