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ámetros 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

Se genera nuevo refresh al refrescar

Blacklist tras Rotación

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

401

Token expirado o inválido

Refrescar el token o hacer login de nuevo

401

Token no proporcionado

Añadir cabecera Authorization: Bearer <token>

401

Refresh token expirado

Realizar login completo de nuevo

403

Usuario sin permisos para el recurso

Verificar rol y acceso al módulo

Buenas Prácticas

  1. Almacena tokens de forma segura: Nunca expongas tokens en URLs o logs.

  2. Refresca proactivamente: Refresca el access token antes de que expire.

  3. Maneja la expiración: Si recibes un 401, intenta refrescar antes de redirigir al login.

  4. Usa HTTPS: Todas las peticiones deben ir sobre HTTPS en producción.

  5. No compartas tokens: Cada integración debe tener su propio usuario y credenciales.