Comment obtenir l'IP de l'utilisateur dans Django?
J'ai une vue comme celle-ci:
# 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())
Mais je reçois cette erreur:
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
Réponses:
Assurez-vous que le proxy inverse (le cas échéant) est correctement configuré (par exemple,
mod_rpaf
installé pour Apache).Remarque: ce qui précède utilise le premier élément dans
X-Forwarded-For
, mais vous voudrez peut-être utiliser le dernier élément (par exemple, dans le cas de Heroku: obtenir la véritable adresse IP du client sur Heroku )Et puis passez-lui la requête comme argument;
la source
ip = get_client_ip(request)
dans votre fonction d'affichage.X-Forwarded-For: client, proxy1, proxy2
. La première adresse est donc celle du client.Vous pouvez utiliser django-ipware qui prend en charge Python 2 et 3 et gère IPv4 et IPv6 .
Installer:
pip install django-ipware
Utilisation simple:
Utilisation avancée:
En-tête personnalisé - En-tête de demande personnalisé pour ipware à regarder:
Nombre de proxy - Le serveur Django est derrière un nombre fixe de proxys:
Trusted Proxies - Le serveur Django est derrière un ou plusieurs proxy connus et approuvés:
Remarque: lisez cet avis .
la source
IPWARE_META_PRECEDENCE_LIST
la variable que vous utilisez, ou utilisez une alternative comme pypi.python.org/pypi/WsgiUnproxyget_client_ip()
.get_real_ip
est obsolète et sera supprimé dans la version 3.0.La réponse d'Alexandre est excellente, mais il lui manque la gestion des proxys qui renvoient parfois plusieurs IP dans l'en-tête HTTP_X_FORWARDED_FOR.
La véritable IP est généralement à la fin de la liste, comme expliqué ici: http://en.wikipedia.org/wiki/X-Forwarded-For
La solution est une simple modification du code d'Alexandre:
la source
request.META
j'inclus une valeur par défaut, car les en-têtes sont souvent en erreur:request.META.get('REMOTE_ADDR', None)
Je voudrais suggérer une amélioration de la réponse de Yanchenko.
Au lieu de prendre la première IP de la liste X_FORWARDED_FOR, je prends la première qui, dans une IP interne non connue, car certains routeurs ne respectent pas le protocole, et vous pouvez voir les IPS internes comme la première valeur de la liste.
J'espère que cela aide les autres Googleurs qui ont le même problème.
la source
voici une courte ligne pour y parvenir:
la source
La solution la plus simple (au cas où vous utilisez fastcgi + nignx) est ce qu'itgorilla a commenté:
Ps: J'ai ajouté cette réponse juste pour rendre sa solution plus visible.
la source
proxy_set_header REMOTE_ADDR $remote_addr;
ne résout pas le problème lorsqu'il est ajouté à nginx.conf.No More confusion Dans les versions récentes de Django, il est clairement mentionné que l'adresse IP du client est disponible à l'adresse
pour plus d'informations, consultez les documents Django
la source
Dans mon cas, rien de ce qui précède ne fonctionne, donc je dois vérifier
uwsgi
+django
le code source et passer un paramètre statique dans nginx et voir pourquoi / comment, et ci-dessous ce que j'ai trouvé.Info env:
version python : version
2.7.5
Django:
(1, 6, 6, 'final', 0)
version nginx:
nginx/1.6.0
uwsgi:
2.0.7
Env setting info:
nginx en tant que proxy inverse écoutant au port
80
uwsgi en tant que socket unix en amont, répondra éventuellement à la demandeInformations de configuration de Django:
configuration nginx:
obtenir tous les paramètres dans l'application django:
Conclusion:
Donc, fondamentalement, vous devez spécifier exactement le même nom de champ / paramètre dans nginx, et utiliser
request.META[field/param]
dans l'application django.Et maintenant, vous pouvez décider d'ajouter un middleware (intercepteur) ou simplement d'analyser
HTTP_X_FORWARDED_FOR
certaines vues.la source
La raison pour laquelle la fonctionnalité a été supprimée de Django à l'origine était que l'en-tête ne pouvait pas être approuvé en fin de compte. La raison en est qu'il est facile d'usurper. Par exemple, la façon recommandée de configurer un proxy inverse nginx est de:
Quand vous faites:
Votre nginx sur myhost.com enverra à partir de maintenant:
le
X-Real-IP
sera l'IP du premier proxy précédent si vous suivez les instructions à l'aveugle.Dans le cas où la confiance en vos utilisateurs est un problème, vous pouvez essayer quelque chose comme
django-xff
: https://pypi.python.org/pypi/django-xff/la source
Il me manquait également un proxy dans la réponse ci-dessus. J'ai utilisé
get_ip_address_from_request
de django_easy_timezones .Et voici la méthode
get_ip_address_from_request
, IPv4 et IPv6 prêt:la source
Dans django.VERSION (2, 1, 1, 'final', 0) gestionnaire de demande
si vous appelez le code ci-dessus deux fois,
AttributeError ("'_ io.BytesIO' objet n'a pas d'attribut 'stream'",)
AttributeError ("L'objet 'LimitedStream' n'a pas d'attribut 'raw'"))
la source