El libro de Django 1.0

15.1. Qué es middleware

Un componente middleware es simplemente una clase Python que se ajusta a una cierta API. Antes de entrar en los aspectos formales de los que es esa API, miremos un ejemplo muy sencillo.

Sitios de tráfico alto a menudo necesitan implementar Django detrás de un proxy de balanceo de carga (mira el Capítulo 20). Esto puede causar unas pequeñas complicaciones, una de las cuales es que la IP remota de cada petición (request.META["REMOTE_IP"]) será la del balanceador de carga, no la IP real que realiza la petición. Los balanceadores de carga manejan esto estableciendo una cabecera especial, X-Forwarded-For, con el valor real de la dirección IP que realiza la petición.

Así que aquí está una pequeña parte de middleware que le permite a los sitios que se ejecutan detrás de un proxy ver la dirección IP correcta en request.META["REMOTE_ADDR"]:

class SetRemoteAddrFromForwardedFor(object):
    def process_request(self, request):
        try:
            real_ip = request.META['HTTP_X_FORWARDED_FOR']
        except KeyError:
            pass
        else:
            # HTTP_X_FORWARDED_FOR can be a comma-separated list of IPs.
            # Take just the first one.
            real_ip = real_ip.split(",")[0]
            request.META['REMOTE_ADDR'] = real_ip

Si instalas esto (mira la siguiente sección), el valor de X-Forwarded-For de todas las peticiones será automáticamente insertado en request.META['REMOTE_ADDR']. Esto significa que tus aplicaciones Django no necesitan conocer si están detrás de un proxy de balanceo de carga o no, pueden simplemente acceder a request.META['REMOTE_ADDR'], y eso funcionará si se usa un proxy o no.

De hecho, es una necesidad tan común, que esta pieza de middleware ya viene incorporada en Django. Esta ubicada en django.middleware.http, y puedes leer más sobre ella en la siguiente sección.