Wie erhalte ich die IP des Benutzers in Django?
Ich habe eine Ansicht wie diese:
# 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())
Aber ich bekomme diesen Fehler:
KeyError at /mypage/
'REMOTE_ADDR'
Request Method: GET
Request URL: http://mywebsite.com/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
Antworten:
Stellen Sie sicher, dass Sie den Reverse-Proxy (falls vorhanden) richtig konfiguriert haben (z. B.
mod_rpaf
für Apache installiert).Hinweis: In den obigen Abschnitten wird das erste Element in verwendet
X-Forwarded-For
, Sie möchten jedoch möglicherweise das letzte Element verwenden (z. B. im Fall von Heroku: Erhalten Sie die echte IP-Adresse des Kunden auf Heroku ).Und dann übergeben Sie einfach die Anfrage als Argument an sie;
quelle
ip = get_client_ip(request)
Ihre Ansichtsfunktion auf.X-Forwarded-For: client, proxy1, proxy2
. Die erste Adresse ist also die des Kunden.Sie können Django-IPware verwenden , die Python 2 und 3 unterstützt und IPv4 und IPv6 verarbeitet .
Installieren:
pip install django-ipware
Einfache Verwendung:
Erweiterte Verwendung:
Benutzerdefinierter Header - Benutzerdefinierter Anforderungsheader für IPware:
Proxy-Anzahl - Der Django-Server steht hinter einer festen Anzahl von Proxys:
Vertrauenswürdige Proxies - Der Django-Server steht hinter einem oder mehreren bekannten und vertrauenswürdigen Proxys:
Hinweis: Lesen Sie diesen Hinweis .
quelle
IPWARE_META_PRECEDENCE_LIST
Sie immer die Variable ein, die Sie verwenden, oder verwenden Sie eine Alternative wie pypi.python.org/pypi/WsgiUnproxyget_client_ip()
.get_real_ip
ist veraltet und wird in 3.0 entfernt.Alexanders Antwort ist großartig, aber es fehlt die Behandlung von Proxys, die manchmal mehrere IPs im HTTP_X_FORWARDED_FOR-Header zurückgeben.
Die tatsächliche IP befindet sich normalerweise am Ende der Liste, wie hier erläutert: http://en.wikipedia.org/wiki/X-Forwarded-For
Die Lösung ist eine einfache Modifikation von Alexanders Code:
quelle
request.META
gebe ich normalerweise einen Standardwert an, da die Header häufig falsch sind:request.META.get('REMOTE_ADDR', None)
Ich möchte eine Verbesserung der Antwort von yanchenko vorschlagen.
Anstatt die erste IP in der X_FORWARDED_FOR-Liste zu verwenden, nehme ich die erste, die in keiner bekannten internen IP enthalten ist, da einige Router das Protokoll nicht respektieren und Sie interne IPs als ersten Wert der Liste sehen können.
Ich hoffe, das hilft anderen Googlern, die das gleiche Problem haben.
quelle
Hier ist ein kurzer Einzeiler, um dies zu erreichen:
quelle
Die einfachste Lösung (falls Sie fastcgi + nignx verwenden) ist das, was itgorilla kommentiert hat:
Ps: Ich habe diese Antwort hinzugefügt, um seine Lösung sichtbarer zu machen.
quelle
proxy_set_header REMOTE_ADDR $remote_addr;
Lindert das Problem nicht, wenn es zu nginx.conf hinzugefügt wird.Keine Verwirrung mehr In den jüngsten Versionen von Django wird deutlich erwähnt, dass die IP-Adresse des Clients unter verfügbar ist
Weitere Informationen finden Sie in den Django-Dokumenten
quelle
In meinem Fall funktioniert keiner der oben genannten Punkte , daher muss ich
uwsgi
+django
Quellcode überprüfen und statische Parameter in Nginx übergeben und sehen, warum / wie und unten ist, was ich gefunden habe.Env info:
Python-Version:
2.7.5
Django-
(1, 6, 6, 'final', 0)
Version:
nginx/1.6.0
Nginx- Version: uwsgi:
2.0.7
Informationen zur Umgebungseinstellung:
nginx als Reverse-Proxy, der am Port
80
uwsgi als Upstream-Unix-Socket lauscht, wird schließlich auf die Anfrage antwortenDjango Konfigurationsinfo:
nginx config:
alle params in der django app bekommen:
Fazit:
Grundsätzlich müssen Sie in nginx genau den gleichen Feld- / Parameternamen angeben und
request.META[field/param]
in der Django-App verwenden.Und jetzt können Sie entscheiden, ob Sie eine Middleware (Interceptor) hinzufügen oder nur
HTTP_X_FORWARDED_FOR
bestimmte Ansichten analysieren möchten.quelle
Der Grund, warum die Funktionalität ursprünglich aus Django entfernt wurde, war, dass dem Header letztendlich nicht vertraut werden kann. Der Grund ist, dass es leicht zu fälschen ist. Die empfohlene Methode zum Konfigurieren eines Nginx-Reverse-Proxys lautet beispielsweise:
Wenn Sie das tun:
Ihr Nginx in myhost.com sendet weiter:
Das
X-Real-IP
wird die IP - Adresse des ersten vorherigen Proxy, wenn Sie die Anweisungen blind folgen.Wenn es ein Problem ist, zu vertrauen, wer Ihre Benutzer sind, können Sie Folgendes versuchen
django-xff
: https://pypi.python.org/pypi/django-xff/quelle
In der obigen Antwort fehlte mir auch der Proxy. Ich habe
get_ip_address_from_request
von django_easy_timezones verwendet .Und hier ist Methode
get_ip_address_from_request
, IPv4 und IPv6 bereit:quelle
In django.VERSION (2, 1, 1, 'final', 0) Anforderungshandler
Wenn Sie den obigen Code zweimal aufrufen, erhalten Sie möglicherweise
AttributeError ("'_ io.BytesIO' Objekt hat kein Attribut 'stream'",)
AttributeError ("'LimitedStream' Objekt hat kein Attribut 'raw'")
quelle