Files
pagasis/docs/CHANGELOG_FIX.md
T
2025-10-15 23:45:32 -06:00

6.8 KiB

Changelog - Corrección de Errores de Autenticación

Fecha: 2025-10-12 Versión: 1.0.1

Problemas Resueltos

1. Error 403 CSRF en Login desde Navegador

Síntoma: Al intentar hacer login desde el navegador web, el backend retornaba error 403 (Forbidden) con mensaje "Acceso denegado (permisos insuficientes)".

Causa Raíz: Django estaba aplicando validación CSRF a todas las rutas, incluyendo las rutas de API REST que usan JWT para autenticación. El middleware CsrfViewMiddleware rechazaba requests sin token CSRF.

Solución Implementada:

  1. Creado nuevo middleware DisableCSRFOnAPIMiddleware en backend/mac_attendance/middleware.py

    • Desactiva validación CSRF para todas las rutas que coincidan con ^api/.*$
    • Colocado antes de CsrfViewMiddleware en la cadena de middleware
  2. Actualizado settings.py:

    • Agregado CSRF_EXEMPT_URLS = [r'^api/.*$']
    • Actualizado CORS_ALLOWED_ORIGINS para incluir http://localhost
    • Agregado CSRF_TRUSTED_ORIGINS para desarrollo local
    • Agregado middleware en posición correcta (línea 45)
  3. Configuración final de middleware:

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'mac_attendance.middleware.DisableCSRFOnAPIMiddleware',  # ← NUEVO
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'mac_attendance.middleware.AuditMiddleware',
]

Resultado: Login desde navegador funciona correctamente sin error 403


2. Endpoint /api/ Expuesto Públicamente

Síntoma: Cualquier usuario no autenticado podía acceder a /api/ y /api/docs/ para ver información sobre todos los endpoints del sistema.

Riesgo de Seguridad: Exposición de información sensible sobre la estructura de la API.

Solución Implementada:

  1. Actualizado backend/mac_attendance/urls.py:

    • Agregado decorador @permission_classes([IsAuthenticated]) a función api_root()
    • Agregado decorador @permission_classes([IsAuthenticated]) a función api_docs()
    • Ambos endpoints ahora requieren token JWT válido
  2. Código modificado:

from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated

@api_view(['GET'])
@permission_classes([IsAuthenticated])
def api_root(request):
    """API root endpoint - Returns comprehensive API information (Protected)"""
    # ...

@api_view(['GET'])
@permission_classes([IsAuthenticated])
def api_docs(request):
    """API documentation endpoint (Protected)"""
    # ...

Resultado:

  • /api/ sin autenticación → Error 401 "Las credenciales de autenticación no se proveyeron"
  • /api/ con token válido → Muestra información de la API
  • /api/docs/ ahora también protegido

Archivos Modificados

1. backend/mac_attendance/middleware.py

  • Agregado: Clase DisableCSRFOnAPIMiddleware
  • Líneas: 103-126

2. backend/mac_attendance/settings.py

  • Modificado: Lista MIDDLEWARE (línea 40-51)
  • Agregado: CSRF_EXEMPT_URLS (línea 154)
  • Modificado: CORS_ALLOWED_ORIGINS (línea 140-143)
  • Agregado: CSRF_TRUSTED_ORIGINS (línea 148-151)

3. backend/mac_attendance/urls.py

  • Modificado: Función api_root() - agregado autenticación (línea 23-26)
  • Modificado: Función api_docs() - agregado autenticación (línea 138-140)

4. API_DOCUMENTATION.md

  • Actualizado: Sección "Acceder a la Documentación" con advertencia de autenticación

Testing Realizado

Test 1: Login desde cURL (simulando navegador)

curl -X POST http://localhost/api/auth/login/ \
  -H "Content-Type: application/json" \
  -H "Origin: http://localhost" \
  -d '{"account_number":"3123123"}'

Resultado: Status 200, retorna tokens JWT

Test 2: API Root sin autenticación

curl -X GET http://localhost/api/

Resultado: Status 401, mensaje de error apropiado

Test 3: API Root con autenticación

curl -X GET http://localhost/api/ \
  -H "Authorization: Bearer <token>"

Resultado: Status 200, retorna información de API


Seguridad Mejorada

Antes de la Corrección:

  • Login fallaba con 403 desde navegador
  • /api/ accesible sin autenticación
  • /api/docs/ accesible sin autenticación
  • ⚠️ Información de endpoints expuesta públicamente

Después de la Corrección:

  • Login funciona correctamente desde navegador
  • /api/ requiere autenticación JWT
  • /api/docs/ requiere autenticación JWT
  • Información de API protegida
  • CSRF deshabilitado solo en rutas API (usamos JWT)
  • CSRF sigue activo en panel admin (usa sesiones)

Notas Técnicas

¿Por qué deshabilitar CSRF en API?

Django REST Framework con JWT no necesita protección CSRF porque:

  1. No usa cookies de sesión: JWT se envía en header Authorization
  2. Tokens stateless: No hay estado de sesión en servidor
  3. CORS protege: CORS ya previene requests desde orígenes no autorizados
  4. JWT expira: Tokens tienen tiempo de vida limitado (1 hora)

Alternativa No Recomendada

Usar @csrf_exempt en cada vista → Requiere modificar múltiples archivos Nuestra solución: Middleware centralizado → Un solo punto de configuración


Cómo Probar

1. Desde el navegador (http://localhost)

  1. Abrir la aplicación
  2. Ingresar número de cuenta: 3123123
  3. Click en "Iniciar Sesión"
  4. Debe iniciar sesión exitosamente

2. Verificar protección de /api/

  1. Abrir navegador e ir a http://localhost/api/
  2. Debe mostrar: {"detail": "Las credenciales de autenticación no se proveyeron."}

3. Acceder a /api/ autenticado

  1. Hacer login primero
  2. Copiar el access_token
  3. Usar extensión de navegador o Postman:
  4. Debe mostrar información completa de la API

Próximos Pasos (Opcional)

  • Implementar rate limiting específico para login (ya existe global)
  • Agregar logs de accesos exitosos/fallidos a /api/
  • Considerar implementar API key para documentación pública
  • Agregar tests automatizados para validación CSRF

Contacto

Si encuentras algún problema con estas correcciones, revisa:

  1. Logs del backend: docker-compose logs backend
  2. Logs de nginx: docker-compose logs nginx
  3. Consola del navegador (F12) para ver errores de JavaScript

Revisado y probado: Contenedores actualizados: Documentación actualizada: