============== 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 --------------- .. code-block:: text POST /accounts/api/login/ Solicita un par de tokens (access + refresh) proporcionando credenciales de usuario. **Request body:** .. code-block:: json { "username": "admin", "password": "mi_password_seguro" } **Respuesta exitosa (200):** .. code-block:: json { "access": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNzA5MjM0NTY3LCJ1c2VyX2lkIjoxfQ.abc123...", "refresh": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoicmVmcmVzaCIsImV4cCI6MTcwOTgzMjE2NywidXNlcl9pZCI6MX0.def456..." } **Ejemplo con curl:** .. code-block:: bash 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):** .. code-block:: json { "detail": "No se encontró una cuenta activa con las credenciales proporcionadas." } Refrescar Token =============== Endpoint: Token Refresh ----------------------- .. code-block:: text 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:** .. code-block:: json { "refresh": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..." } **Respuesta exitosa (200):** .. code-block:: json { "access": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.nuevo_access_token...", "refresh": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.nuevo_refresh_token..." } **Ejemplo con curl:** .. code-block:: bash 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: .. code-block:: text Authorization: Bearer **Ejemplo completo — listar sitios web:** .. code-block:: bash # 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:** .. code-block:: bash 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 ===================== .. list-table:: Parámetros JWT :header-rows: 1 :widths: 35 25 40 * - 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: .. code-block:: javascript // 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 ==================================== .. list-table:: :header-rows: 1 :widths: 15 40 45 * - 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 `` * - ``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.