CAPÍTULO 2 · Del arranque a una base protegida
Mirar lo que ocurre antes de llegar a una vista
Hasta aquí hemos visto archivos y comandos. Para avanzar conviene seguir una petición completa: el navegador solicita una dirección, Django prepara el contexto, resuelve la ruta, ejecuta una vista y construye una respuesta. Entre la entrada y la vista hay componentes que pueden examinar la solicitud o detenerla. Si desconocemos ese recorrido, un rechazo parece un obstáculo sin explicación.
El middleware nos permite reconocer esas responsabilidades. En una aplicación que utiliza sesiones, la cookie del navegador participa en recuperar un contexto; cuando hay autenticación, otra pieza establece quién actúa. CSRF atiende un problema diferente: validar determinadas peticiones del navegador que pueden llegar con credenciales adjuntas. No estamos agregando todavía un login a la academia pública, sino entendiendo dónde encajaría en una aplicación privada.
Este recorrido evita resolver errores desactivando controles sin comprenderlos. También nos muestra que algunas decisiones deben aplicarse a todas las respuestas. En lugar de recordarlas dentro de cada módulo, vamos a establecer una política común en la configuración base.
Leer esta parte dentro del relato completo →DEL RELATO A LA PRÁCTICA
Vamos a desarrollar esta decisión con su mapa, explicación, código y ejercicio.
MIRA · CONECTA · COMPRENDE
Controles en el recorrido HTTP
Las flechas resumen el recorrido conceptual. Los controles y dependencias se detallan debajo.
Selecciona una pieza para destacar su responsabilidad.
Leer la explicación del mapa
- Navegador. Envía cookie y petición
- CSRF. Verifica escritura del navegador
- Middleware. Prepara contexto y controles
- Vista. Ejecuta tras las verificaciones
01 / EL PROBLEMA
¿Para qué sirve?
Las cookies se envían automáticamente. Otra página puede intentar inducir una solicitud que aproveche una sesión; CSRF ayuda a impedirlo.
02 / COMPRENDER
El concepto, explicado
SessionMiddleware aporta sesión y AuthenticationMiddleware resuelve usuario. Un middleware de negocio que dependa de request.user debe ejecutarse después.
CSRF y autorización resuelven problemas distintos. Un token válido no concede permiso. Con SessionAuthentication, una escritura autenticada requiere protección CSRF.
MIDDLEWARE se recorre en orden al entrar la petición y en orden inverso al volver la respuesta. SessionMiddleware precede a AuthenticationMiddleware cuando usas sesiones; los permisos personalizados que leen request.user van después de construir la identidad.
En una aplicación empresarial el recorrido habitual incluye SecurityMiddleware, WhiteNoise si aplica, sesiones, CommonMiddleware, CSRF, autenticación, mensajes y clickjacking. Los middlewares propios se colocan según sus dependencias; no copies dos mecanismos de identidad que compitan.
Si CSRF_COOKIE_HTTPONLY=True, un cliente JavaScript no podrá leer esa cookie para armar el header. Obtén el token desde un campo renderizado por csrf_token y prueba el POST. HttpOnly limita lectura desde scripts, pero no elimina XSS.
Continúa con “Seguridad en base.py” para ver el bloque completo de cookies, cabeceras y expiración.
03 / CONSTRUIR
Implementación paso a paso
- Ordena sesión antes de autenticación.
- Distingue páginas HTML y respuestas API.
- Incluye token en POST, PUT y DELETE con sesión.
- No exemptes globalmente los endpoints humanos.
04 / APLICAR
Ejemplo en SensorHub
<!-- Template de una aplicación con sesión -->
<form id="sensor-form">{% csrf_token %}</form>
<script type="module">
const token = document.querySelector("[name=csrfmiddlewaretoken]").value;
await fetch("/api/sensors/", {
method: "POST", credentials: "same-origin",
headers: {"Content-Type": "application/json", "X-CSRFToken": token},
body: JSON.stringify({code: "TEMP-01", station: stationId})
});
</script>
# Orden de referencia para una app empresarial con sesión (base.py):
# MIDDLEWARE = [
# "django.middleware.security.SecurityMiddleware",
# "whitenoise.middleware.WhiteNoiseMiddleware",
# "django.contrib.sessions.middleware.SessionMiddleware",
# "django.middleware.common.CommonMiddleware",
# "django.middleware.csrf.CsrfViewMiddleware",
# "django.contrib.auth.middleware.AuthenticationMiddleware",
# "django.contrib.messages.middleware.MessageMiddleware",
# "django.middleware.clickjacking.XFrameOptionsMiddleware",
# ]
# Auth middleware propio: después de la identidad que necesite leer.
# Este ejemplo empresarial no se añade a la academia pública.Cómo leer el ejemplo
- El token del DOM permite evitar depender de leer la cookie mediante JS.
- La variable stationId debe provenir de la selección validada del cliente.
- El serializer y el permiso siguen siendo necesarios después de CSRF.
Error habitual
Una API que devuelve una página de login en vez de un error JSON puede confundir al cliente. Define su contrato de sesión expirada.
05 / PRACTICAR
Tu turno
Prueba un POST autenticado sin token usando Client(enforce_csrf_checks=True).
Ver solución orientativa
El servidor debe rechazarlo. Luego obtén token válido del template y repite para verificar que el flujo legítimo funciona.
06 / VERIFICAR
Cómo sabes que funciona
- Escrituras autenticadas requieren token válido.
- Un token válido no permite acciones fuera del rol.
Para profundizar
Documentación oficial para comprobar configuración, permisos y condiciones vigentes. Revisión del tema: 11 de octubre de 2026.
CONTINUAR LA EXPERIENCIA
El siguiente paso del recorrido:
Seguridad en base.py: cookies, CSRF y cabeceras →Continuar en modo relato