¿Cómo obtengo la dirección IP del usuario en Django?

Resuelto avatar asked hace 13 años • 15 respuestas

¿Cómo obtengo la IP del usuario en Django?

Tengo una vista como esta:

# Create your views
from django.contrib.gis.utils import GeoIP
from django.template import  RequestContext
from django.shortcuts import render_to_response

def home(request):
  g = GeoIP()
  client_ip = request.META['REMOTE_ADDR']
  lat,long = g.lat_lon(client_ip)
  return render_to_response('home_page_tmp.html',locals())

Pero me sale este error:

KeyError at /mypage/
    'REMOTE_ADDR'
    Request Method: GET
    Request URL:    http://mywebsite.example/mypage/
    Django Version: 1.2.4
    Exception Type: KeyError
    Exception Value:
    'REMOTE_ADDR'
    Exception Location: /mysite/homepage/views.py in home, line 9
    Python Executable:  /usr/bin/python
    Python Version: 2.6.6
    Python Path:    ['/mysite', '/usr/local/lib/python2.6/dist-packages/flup-1.0.2-py2.6.egg', '/usr/lib/python2.6', '/usr/lib/python2.6/plat-linux2', '/usr/lib/python2.6/lib-tk', '/usr/lib/python2.6/lib-old', '/usr/lib/python2.6/lib-dynload', '/usr/local/lib/python2.6/dist-packages', '/usr/lib/python2.6/dist-packages', '/usr/lib/pymodules/python2.6']
    Server time:    Sun, 2 Jan 2011 20:42:50 -0600
avatar avatar Jan 03 '11 09:01 avatar
Aceptado
def get_client_ip(request):
    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
    if x_forwarded_for:
        ip = x_forwarded_for.split(',')[0]
    else:
        ip = request.META.get('REMOTE_ADDR')
    return ip

Asegúrese de tener el proxy inverso (si lo hay) configurado correctamente (por ejemplo, mod_rpafinstalado para Apache).

Nota: lo anterior usa el primer elemento en X-Forwarded-For, pero es posible que desees usar el último elemento (por ejemplo, en el caso de Heroku: Obtener la dirección IP real del cliente en Heroku )

Y luego simplemente pásele la solicitud como argumento;

get_client_ip(request)

Documentación de Django para HttpRequest.META

yanchenko avatar Jan 03 '2011 04:01 yanchenko

Puede utilizar django-ipware , que admite Python 2 y 3 y maneja IPv4 e IPv6 .

Instalar:

pip install django-ipware

Uso sencillo:

# In a view or a middleware where the `request` object is available

from ipware import get_client_ip
ip, is_routable = get_client_ip(request)
if ip is None:
    # Unable to get the client's IP address
else:
    # We got the client's IP address
    if is_routable:
        # The client's IP address is publicly routable on the Internet
    else:
        # The client's IP address is private

# Order of precedence is (Public, Private, Loopback, None)

Uso avanzado:

  • Encabezado personalizado: encabezado de solicitud personalizado para que ipware lo vea:

    i, r = get_client_ip(request, request_header_order=['X_FORWARDED_FOR'])
    i, r = get_client_ip(request, request_header_order=['X_FORWARDED_FOR', 'REMOTE_ADDR'])
    
  • Recuento de proxy: el servidor Django está detrás de un número fijo de proxies:

    i, r = get_client_ip(request, proxy_count=1)
    
  • Proxies confiables: el servidor Django está detrás de uno o más servidores proxy conocidos y confiables:

    i, r = get_client_ip(request, proxy_trusted_ips=('177.2.2.2'))
    
    # For multiple proxies, simply add them to the list
    i, r = get_client_ip(request, proxy_trusted_ips=('177.2.2.2', '177.3.3.3'))
    
    # For proxies with fixed sub-domain and dynamic IP addresses, use partial pattern
    i, r = get_client_ip(request, proxy_trusted_ips=('177.2.', '177.3.'))
    

Nota: lea este aviso .

Val Neekman avatar Apr 24 '2013 23:04 Val Neekman

La respuesta de Alexander es excelente, pero carece del manejo de servidores proxy que a veces devuelven múltiples IP en el encabezado HTTP_X_FORWARDED_FOR.

La IP real suele estar al final de la lista, como se explica aquí: http://en.wikipedia.org/wiki/X-Forwarded-For

La solución es una simple modificación del código de Alexander:

def get_client_ip(request):
    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
    if x_forwarded_for:
        ip = x_forwarded_for.split(',')[-1].strip()
    else:
        ip = request.META.get('REMOTE_ADDR')
    return ip
Sævar avatar May 12 '2011 09:05 Sævar

No más confusión En las versiones recientes de Django se menciona claramente que la dirección IP del cliente está disponible en

request.META.get("REMOTE_ADDR")

para obtener más información, consulte los documentos de Django

Pardhu avatar Feb 20 '2020 10:02 Pardhu