Middleware

Este documento explica todos los componentes de middleware que vienen con Django. Para obtener información sobre cómo utilizarlos y cómo escribir tus propios middleware, consulta la guía de uso de middleware <https://docs.djangoproject.com/es/4.1/topics/http/middleware/>_.

Los middleware disponibles

Middleware de caché

class UpdateCacheMiddleware[fuente]
class FetchFromCacheMiddleware[fuente]

Habilita el caché para todo el sitio. Si estos están habilitados, cada página generada por Django se cacheará durante tanto tiempo como lo defina la configuración CACHE_MIDDLEWARE_SECONDS. Consulte la documentación del caché <topics/cache>.

Middleware «común»

class CommonMiddleware[fuente]
response_redirect_class

Por defecto utiliza HttpResponsePermanentRedirect. Sustituye CommonMiddleware por una subclase y sobreescriba el atributo para personalizar los redireccionamientos emitidos por el middleware.

Agrega algunas comodidades para perfeccionistas:

  • Prohibe el acceso a los agentes de usuario en la configuración DISALLOWED_USER_AGENTS, que debe ser una lista de objetos de expresiones regulares compiladas.

  • Realiza reescrituras de URL basadas en las configuraciones APPEND_SLASH y PREPEND_WWW.

    Si APPEND_SLASH es True y la URL inicial no termina con una barra diagonal, y no se encuentra en el URLconf, entonces se forma una nueva URL agregando una barra diagonal al final. Si esta nueva URL se encuentra en el URLconf, entonces Django redirige la solicitud a esta nueva URL. De lo contrario, la URL inicial se procesa como de costumbre.

    Por ejemplo, foo.com/bar se redirigirá a foo.com/bar/ si no tienes un patrón de URL válido para foo.com/bar pero tienes un patrón válido para foo.com/bar/.

    Si PREPEND_WWW es True, las URLs que carecen de un «www.» en la parte delantera se redirigirán a la misma URL con un «www.» en la parte delantera.

    Ambas opciones están pensadas para normalizar URLs. La filosofía es que cada URL debe existir en uno y sólo uno de esos lugares. Técnicamente, una URL foo.com/bar es distinta de foo.com/bar/ – un indexer de motores de búsqueda trataría a ambos como URLs separadas – por lo que es la mejor práctica normalizar URLs.

    Si es necesario, las vistas individuales pueden excluirse del comportamiento APPEND_SLASH utilizando el decorador no_append_slash():

    from django.views.decorators.common import no_append_slash
    
    
    @no_append_slash
    def sensitive_fbv(request, *args, **kwargs):
        """View to be excluded from APPEND_SLASH."""
        return HttpResponse()
    
  • Establece el encabezado Content-Length para respuestas no de transmisión.

class BrokenLinkEmailsMiddleware[fuente]

Middleware GZip

class GZipMiddleware[fuente]
max_random_bytes

Por defecto, 100. Sustituye GZipMiddleware y sobreescribe la atributo para cambiar el número máximo de bytes aleatorios que se incluyen con respuestas comprimidas.

Nota

Los investigadores de seguridad revelaron que cuando se utilizan técnicas de compresión (incluyendo GZipMiddleware) en un sitio web, el sitio puede volverse vulnerable a una serie de posibles ataques.

Para mitigar los ataques, Django implementa una técnica llamada Heal The Breach (HTB). Agrega hasta 100 bytes (ver max_random_bytes) de bytes aleatorios a cada respuesta para hacer que los ataques sean menos efectivos.

Para obtener más detalles, consulte el paper BREACH (PDF), breachattack.com y el paper Heal The Breach (HTB).

Los textos traducidos son:

Este middleware debe colocarse antes de cualquier otro middleware que necesite leer o escribir el cuerpo de respuesta para que la compresión ocurra después.

No comprimirá contenido si alguna de las siguientes condiciones son verdaderas:

  • El cuerpo del contenido tiene menos de 200 bytes de largo.

  • La respuesta ya ha establecido el encabezado Content-Encoding.

  • La solicitud (el navegador) no envió un encabezado Accept-Encoding que contenga gzip.

Si la respuesta tiene un encabezado ETag, el ETag se hace débil para cumplir con RFC 9110 Section 8.8.1.

Puedes aplicar compresión GZip a vistas individuales utilizando el decorador de función gzip_page().

Middleware de GET condicional

class ConditionalGetMiddleware[fuente]

Gestiona operaciones GET condicionales. Si la respuesta no tiene un encabezado ETag, el middleware agrega uno si es necesario. Si la respuesta tiene un encabezado ETag o Last-Modified y la solicitud tiene If-None-Match o If-Modified-Since, la respuesta se reemplaza por una HttpResponseNotModified.

Puedes manejar operaciones GET condicionales con vistas individuales utilizando el decorador de función conditional_page().

Middleware de localización

class LocaleMiddleware[fuente]
response_redirect_class

Por defecto, utiliza la clase HttpResponseRedirect. Sustituye LocaleMiddleware y sobrescribe la propiedad para personalizar los redireccionamientos emitidos por el middleware.

Permite la selección del idioma basada en datos de la solicitud. Personaliza el contenido para cada usuario. Consulta la documentación de internacionalización :doc:` </topics/i18n/translation>`.

Middleware de mensajes

class MessageMiddleware[fuente]

Permite el soporte a mensajes basados en cookies y sesiones. Consulta la documentación de mensajes :doc:` </ref/contrib/messages>`.

Middleware de seguridad

Advertencia

Si tu situación de despliegue lo permite, es una buena idea que tu servidor web frontal realice la funcionalidad proporcionada por el SecurityMiddleware. De esta manera, si hay solicitudes que no son servidas por Django (como archivos estáticos o subidos por usuarios), tendrán las mismas protecciones que las solicitudes a tu aplicación de Django.

class SecurityMiddleware[fuente]

El django.middleware.security.SecurityMiddleware proporciona varias mejoras de seguridad al ciclo solicitud/respuesta. Cada una puede ser habilitada o deshabilitada independientemente mediante una configuración.

  • SECURE_CONTENT_TYPE_NOSNIFF

  • POLÍTICA DE ORIGEN CROS SEGURA

  • INCLUIR SUBDOMINIOS EN LA POLÍTICA HSTS SEGURA

  • CARGAR ANTES PRELOAD HSTS SEGURA

  • TIEMPO DE VIGENCIA DE LA POLÍTICA HSTS SEGURA

  • EXENTES DE REDIRECCIÓN SEGURA

  • POLÍTICA DEL REFERENTE SEGURA

  • DOMINIO SSL SEGURA

  • REDIRECCIONAR A HTTPS

Seguridad de Transporte Estricto

Para sitios que solo deben accederse a través de HTTPS, puedes instruir a los navegadores modernos para que se nieguen a conectar con tu nombre de dominio mediante una conexión insegura (por un período determinado) configurando el encabezado «Strict-Transport-Security» header. Esto reduce tu exposición a algunos ataques MITM (man-in-the-middle) que intentan quitar la SSL.

SecurityMiddleware establecerá este encabezado para usted en todas las respuestas HTTPS si establece la configuración SECURE_HSTS_SECONDS a un valor entero distinto de cero.

Al habilitar HSTS, es una buena idea utilizar primero un pequeño valor para pruebas, por ejemplo, SECURE_HSTS_SECONDS = 3600 durante una hora. Cada vez que el navegador web vea el encabezado HSTS de su sitio, se negará a comunicarse de manera no segura (utilizando HTTP) con su dominio durante el período de tiempo dado. Una vez que confirme que todos los activos se están sirviendo de manera segura en su sitio (es decir, HSTS no ha roto nada), es una buena idea aumentar este valor para que los visitantes infrecuentes estén protegidos (31536000 segundos, es decir, 1 año, es común).

Además, si establece la configuración SECURE_HSTS_INCLUDE_SUBDOMAINS a True, SecurityMiddleware agregará el directive includeSubDomains al encabezado Strict-Transport-Security. Esto se recomienda (asumiendo que todos los subdominios se sirven exclusivamente utilizando HTTPS), de lo contrario, su sitio puede seguir siendo vulnerable a través de una conexión insegura a un subdominio.

Si desea enviar su sitio a la lista de pre carga del navegador, establezca la configuración SECURE_HSTS_PRELOAD a True. Eso agrega el directive preload al encabezado Strict-Transport-Security.

Advertencia

La política HSTS se aplica a su dominio completo, no solo a la URL de la respuesta que establece el encabezado. Por lo tanto, debe utilizarlo solo si todo su dominio se sirve mediante HTTPS sólo.

Los navegadores que respetan correctamente el encabezado HSTS se negarán a permitir que los usuarios bypassen las advertencias y conecten con un sitio con un certificado SSL expirado, firmado por sí mismo o de otra manera inválido. Si utiliza HSTS, asegúrese de que sus certificados estén en buen estado y así sigan.

Nota

Si está desplegado detrás de un equilibrador de carga o servidor proxy inverso, y el encabezado Strict-Transport-Security no se está agregando a sus respuestas, puede ser porque Django no se da cuenta de que está en una conexión segura; es posible que deba establecer la configuración SECURE_PROXY_SSL_HEADER.

Política de Referencia

Los navegadores utilizan el encabezado de Referencia como una forma de enviar información a un sitio sobre cómo llegaron los usuarios. Cuando un usuario hace clic en un enlace, el navegador enviará la URL completa de la página que enlaza como referente. Si bien esto puede ser útil para algunos fines – como determinar quién está enlazando con su sitio – también puede causar preocupaciones sobre la privacidad al informar a un sitio que un usuario estaba visitando otro sitio.

Algunos navegadores tienen la capacidad de aceptar sugerencias sobre si deben enviar el encabezado HTTP Referer cuando un usuario hace clic en un enlace; esta sugerencia se proporciona mediante el encabezado de Política de Referencia. Este encabezado puede sugerir cualquiera de tres comportamientos a los navegadores:

  • Full URL: envía la URL completa en el encabezado Referer. Por ejemplo, si el usuario está visitando https://example.com/page.html, el encabezado Referer contendría "https://example.com/page.html".

  • Origen solo: envía solo el «origen» en el remitente. El origen consiste en el esquema, host y (opcionalmente) número de puerto. Por ejemplo, si el usuario está visitando https://example.com/page.html, el origen sería https://example.com/.

  • Sin remitente: no envíe ningún encabezado Referer.

Hay dos tipos de condiciones que este encabezado puede decirle a un navegador que tenga en cuenta:

  • Igual origen versus cruzado: un enlace desde https://example.com/1.html a https://example.com/2.html es igual de origen. Un enlace desde https://example.com/page.html a https://not.example.com/page.html es cruzado.

  • Descenso del protocolo: un descenso ocurre si la página que contiene el enlace se sirve mediante HTTPS, pero la página a la que se vincula no se sirve mediante HTTPS.

Advertencia

Cuando tu sitio se sirve mediante HTTPS, el sistema de protección CSRF de Django requiere que el encabezado Referer esté presente, por lo tanto deshabilitar completamente el encabezado Referer interferirá con la protección CSRF. Para obtener los beneficios más importantes de deshabilitar los encabezados Referer mientras se mantiene la protección CSRF, considera habilitar solo remitentes de origen igual.

SecurityMiddleware puede configurar el encabezado Referrer-Policy para usted, basándose en la SECURE_REFERRER_POLICY configuración (tenga en cuenta la ortografía: los navegadores envían un encabezado Referer cuando un usuario hace clic en un enlace, pero el encabezado que instruye a un navegador si debe hacerlo se escribe Referrer-Policy). Los valores válidos para esta configuración son:

no-referrer

Instruye al navegador que envíe ningún remitente para los enlaces clicados en este sitio.

no-referrer-when-downgrade

Instruye al navegador para que envíe una URL completa como referente, pero solo cuando no se produce un descenso de protocolo.

origen

Instruye al navegador para que envíe solo el origen y no la URL completa como referente.

origin-when-cross-origin

Instruye al navegador para que envíe la URL completa como referente para enlaces de mismo origen, y solo el origen para enlaces de origen cruzado.

same-origin

Instruye al navegador para que envíe una URL completa, pero solo para enlaces de mismo origen. No se enviará ningún referente para enlaces de origen cruzado.

strict-origin

Instruye al navegador para que envíe solo el origen y no la URL completa, y para que no envíe ningún referente cuando se produce un descenso de protocolo.

strict-origin-when-cross-origin

Instruye al navegador para que envíe la URL completa cuando el enlace es de origen mismo y no se produce una disminución del protocolo; envía solo el origen cuando el enlace es de origen cruzado y no se produce una disminución del protocolo; y ningún remitente cuando se produce una disminución del protocolo.

unsafe-url

Instruye al navegador para que siempre envíe la URL completa como remitente.

Valores de política desconocidos

Donde un valor de política es unknown por parte del agente de usuario, es posible especificar múltiples valores de política para proporcionar una alternativa. El último valor especificado que se entiende tiene prioridad. Para apoyar esto, se puede utilizar un iterable o una cadena separada por comas con SECURE_REFERRER_POLICY.

Política del Opener de Origen Cruzado

Algunos navegadores tienen la capacidad de aislar ventanas de nivel superior de otros documentos colocándolas en un grupo de contexto de navegación separado basado en el valor de la cabecera Cross-Origin Opener Policy (COOP). Si un documento aislado de esta manera abre una ventana emergente de origen cruzado, la propiedad window.opener de la ventana emergente será null. Aislar ventanas utilizando COOP es una protección en profundidad contra ataques de origen cruzado, especialmente aquellos como Spectre que permitían el exfiltración de datos cargados en un contexto de navegación compartido.

SecurityMiddleware puede establecer la cabecera Cross-Origin-Opener-Policy para usted, basándose en la configuración SECURE_CROSS_ORIGIN_OPENER_POLICY. Los valores válidos para esta configuración son:

same-origin

Aísla el contexto de navegación exclusivamente a documentos de origen mismo. Los documentos de origen cruzado no se cargan en el mismo contexto de navegación. Esta es la opción por defecto y más segura.

same-origin-allow-popups

Isola el contexto de navegación a documentos con origen igual o aquellos que no establecen COOP o que optan por la isolación estableciendo un COOP de unsafe-none.

unsafe-none

Permite agregar el documento al grupo de contexto de navegación del opener, salvo que el propio opener tenga un COOP de same-origin o same-origin-allow-popups.

X-Content-Type-Options: nosniff

Algunos navegadores intentarán adivinar los tipos de contenido de los activos que descarguen, sobrescribiendo el encabezado Content-Type. Si bien esto puede ayudar a mostrar sitios con servidores configurados incorrectamente, también puede suponer un riesgo para la seguridad.

Si tu sitio sirve archivos subidos por usuarios, un usuario malintencionado podría subir un archivo especialmente diseñado que sería interpretado como HTML o JavaScript por el navegador cuando se esperaba algo inocuo.

Para evitar que el navegador adivine el tipo de contenido y forzarlo a utilizar siempre el tipo proporcionado en el encabezado Content-Type, puedes pasar el encabezado X-Content-Type-Options: nosniff. SecurityMiddleware lo hará para todas las respuestas si la configuración SECURE_CONTENT_TYPE_NOSNIFF es True.

Ten en cuenta que en la mayoría de situaciones de implementación donde Django no está involucrado en servir archivos subidos por usuarios, esta configuración no te ayudará. Por ejemplo, si tu MEDIA_URL se sirve directamente por tu servidor web frontal (nginx, Apache, etc.), entonces querrás establecer este encabezado allí. Por otro lado, si estás utilizando Django para hacer algo como requerir autorización para descargar archivos y no puedes establecer el encabezado usando tu servidor web, esta configuración te será útil.

Redirección SSL

Si tu sitio ofrece conexiones tanto HTTP como HTTPS, la mayoría de los usuarios terminarán con una conexión no segura por defecto. Para la mejor seguridad, debes redirigir todas las conexiones HTTP a HTTPS.

Si estableces la configuración SECURE_SSL_REDIRECT en Verdadero, SecurityMiddleware realizará una redirección permanente (HTTP 301) de todas las conexiones HTTP a HTTPS.

Nota

Por razones de rendimiento, es preferible realizar estas redirecciones fuera de Django, en un equilibrador de carga frontal o servidor proxy inverso como nginx. La configuración SECURE_SSL_REDIRECT está destinada a las situaciones de despliegue donde esto no es una opción.

Si la configuración SECURE_SSL_HOST tiene un valor, todas las redirecciones se enviarán a ese host en lugar del originalmente solicitado.

Si hay algunas páginas en tu sitio que deben estar disponibles sobre HTTP y no ser redirigidas a HTTPS, puedes listar expresiones regulares para coincidir con esas URLs en la configuración SECURE_REDIRECT_EXEMPT.

Nota

Si estás desplegado detrás de un equilibrador de carga o servidor proxy inverso y Django no puede determinar cuando una solicitud realmente es segura, es posible que debas establecer la configuración SECURE_PROXY_SSL_HEADER.

Middleware de sesión

class SessionMiddleware[fuente]

Habilita el soporte para sesiones. Consulte la documentación sobre sesiones.

Middleware del sitio

class CurrentSiteMiddleware[fuente]

Agrega la atributo site que representa el sitio actual a cada objeto HttpRequest entrante. Consulte la documentación de sitios.

Middleware de autenticación

class AuthenticationMiddleware[fuente]

Agrega el atributo user, que representa al usuario actualmente conectado, a cada objeto HttpRequest entrante. Consulte Autenticación en solicitudes web.

class LoginRequiredMiddleware[fuente]

Los textos traducidos son:

redirect_field_name

Por defecto, es "next".

get_login_url()[fuente]

Devuelve la URL a la que se redirigirán las solicitudes no autenticadas. Este resultado es ya sea la URL de inicio de sesión configurada en el decorador login_required() (si no es None), o settings.LOGIN_URL.

get_redirect_field_name()[fuente]

Devuelve el nombre del parámetro de consulta que contiene la URL a la que se debería redirigir al usuario después de un inicio de sesión exitoso. Este resultado es ya sea el campo de redirección configurado en el decorador login_required() (si no es None), o redirect_field_name. Si se devuelve None, no se agregará ningún parámetro de consulta.

Redirige todas las solicitudes no autenticadas a una página de inicio de sesión, excepto para vistas excluidas con login_not_required(). La página de inicio de sesión por defecto es settings.LOGIN_URL, pero se puede personalizar.

Habilita este middleware agregándolo a la configuración MIDDLEWARE después de AuthenticationMiddleware:

MIDDLEWARE = [
    "...",
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    "django.contrib.auth.middleware.LoginRequiredMiddleware",
    "...",
]

Haz que una vista sea pública, permitiendo solicitudes no autenticadas, con login_not_required(). Por ejemplo:

from django.contrib.auth.decorators import login_not_required


@login_not_required
def contact_us(request): ...

Personaliza la URL o el nombre del campo de inicio de sesión para vistas autenticadas con el decorador login_required() para configurar login_url o redirect_field_name, respectivamente. Por ejemplo:

from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
from django.views.generic import View


@login_required(login_url="/books/login/", redirect_field_name="redirect_to")
def book_dashboard(request): ...


@method_decorator(
    login_required(login_url="/books/login/", redirect_field_name="redirect_to"),
    name="dispatch",
)
class BookMetrics(View):
    pass
class RemoteUserMiddleware[fuente]

Middleware para utilizar la autenticación proporcionada por el servidor web. Consulta Cómo autenticarse utilizando REMOTE_USER para obtener detalles de uso.

class PersistentRemoteUserMiddleware[fuente]

Middleware para utilizar la autenticación proporcionada por el servidor web cuando está habilitado solo en la página de inicio de sesión. Consulta Utilizar REMOTE_USER solo en páginas de inicio de sesión para obtener detalles sobre su uso.

Protección contra ataques CSRF mediante middleware

class CsrfViewMiddleware[fuente]

Agrega protección contra solicitudes de Cross Site Request Forgeries añadiendo campos ocultos a las formas POST y comprobando las solicitudes por el valor correcto. Consulte la documentación de protección contra solicitudes de Cross Site Request Forgery en <ref>csrf</ref>.

Puedes agregar protección contra ataques de falsificación de solicitudes entre sitios (Cross Site Request Forgery) a vistas individuales utilizando el decorador csrf_protect().

X-Frame-Options middleware

class XFrameOptionsMiddleware[fuente]

Sencillo: protección contra clickjacking mediante el encabezado X-Frame-Options <ref>clickjacking/</ref>.

Orden de middleware

Aquí tienes algunas pautas sobre la ordenación de las clases de middleware de Django variadas:

  1. SecurityMiddleware

    Debería ir cerca de la parte superior de la lista si vas a activar el redireccionamiento SSL, ya que evita pasar por una serie de middleware innecesarios.

  2. ActualizaMiddlewareDeCaché

    Antes de aquellos que modifican el encabezado Vary (SessionMiddleware, GZipMiddleware, LocaleMiddleware).

  3. GZipMiddleware

    Antes de cualquier middleware que pueda cambiar o utilizar el cuerpo de la respuesta.

    Después de UpdateCacheMiddleware: Modifica el encabezado Vary.

  4. SesionMiddleware

    Antes de cualquier middleware que pueda levantar una excepción para disparar una vista de error (como PermissionDenied), si estás utilizando CSRF_USE_SESSIONS.

    Después de UpdateCacheMiddleware: Modifica el encabezado Vary.

  5. CondicionalGetMiddleware

    Antes de cualquier middleware que pueda cambiar la respuesta (establece el encabezado ETag).

    Después de GZipMiddleware no calculará un encabezado ETag en contenido comprimido con Gzip.

  6. LocaleMiddleware

    Una de las más altas, después de SessionMiddleware (utiliza datos de sesión) y UpdateCacheMiddleware (modifica el encabezado Vary).

  7. CommonMiddleware

    Antes de cualquier middleware que pueda cambiar la respuesta (establece el encabezado Content-Length). Un middleware que aparece antes de CommonMiddleware y cambia la respuesta debe restablecer Content-Length.

    Cerca de la parte superior: redirige cuando APPEND_SLASH o PREPEND_WWW están configurados en True.

    Después de SessionMiddleware si estás utilizando CSRF_USE_SESSIONS.

  8. CsrfViewMiddleware

    Antes de cualquier middleware de vista que asuma que se han atendido los ataques CSRF.

    Antes de RemoteUserMiddleware o cualquier otro middleware de autenticación que pueda realizar una sesión de inicio y rotar el token CSRF, antes de llamar al conjunto de middleware.

    Después de SessionMiddleware si estás utilizando CSRF_USE_SESSIONS.

  9. AuthenticationMiddleware

    Después de SessionMiddleware: utiliza almacenamiento de sesión.

  10. LoginRequiredMiddleware

    Después de AuthenticationMiddleware: utiliza el objeto del usuario.

  11. MessageMiddleware

    Después de SessionMiddleware: puede utilizar almacenamiento basado en sesión.

  12. FetchFromCacheMiddleware

    Después de cualquier middleware que modifique el encabezado Vary: ese encabezado se utiliza para elegir un valor para la clave hash del caché.

  13. FlatpageFallbackMiddleware

    Debería estar cerca de la parte inferior ya que es un tipo de middleware de último recurso.

  14. RedirectFallbackMiddleware

    Debería estar cerca de la parte inferior ya que es un tipo de middleware de último recurso.