Jak uzyskać adres IP użytkownika w django?
Mam taki widok:
# 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())
Ale pojawia się ten błąd:
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
Odpowiedzi:
Upewnij się, że masz odwrotne proxy (jeśli istnieje) poprawnie skonfigurowane (np.
mod_rpaf
Zainstalowane dla Apache).Uwaga: powyższe wykorzystuje pierwszy element w
X-Forwarded-For
, ale możesz chcieć użyć ostatniego elementu (np. W przypadku Heroku: Uzyskaj prawdziwy adres IP klienta na Heroku )A następnie po prostu przekaż żądanie jako argument;
źródło
ip = get_client_ip(request)
funkcję widoku.X-Forwarded-For: client, proxy1, proxy2
. Tak więc pierwszy adres należy do klienta.Możesz użyć django-ipware, które obsługuje Python 2 i 3 i obsługuje IPv4 i IPv6 .
Zainstalować:
pip install django-ipware
Proste użycie:
Zaawansowane użycie:
Niestandardowy nagłówek - niestandardowy nagłówek żądania dla ipware do obejrzenia:
Liczba serwerów proxy - serwer Django stoi za stałą liczbą serwerów proxy:
Zaufane proxy - serwer Django stoi za co najmniej jednym znanym i zaufanym proxy:
Uwaga: przeczytaj to powiadomienie .
źródło
IPWARE_META_PRECEDENCE_LIST
zmienną, której używasz, lub użyj alternatywy, takiej jak pypi.python.org/pypi/WsgiUnproxyget_client_ip()
.get_real_ip
jest przestarzałe i zostanie usunięty w wersji 3.0.Odpowiedź Aleksandra jest świetna, ale brakuje obsługi serwerów proxy, które czasami zwracają wiele adresów IP w nagłówku HTTP_X_FORWARDED_FOR.
Rzeczywiste IP znajduje się zwykle na końcu listy, jak wyjaśniono tutaj: http://en.wikipedia.org/wiki/X-Forwarded-For
Rozwiązaniem jest prosta modyfikacja kodu Aleksandra:
źródło
request.META
, dołączam wartość domyślną, ponieważ nagłówki często się mylą:request.META.get('REMOTE_ADDR', None)
Chciałbym zasugerować poprawę odpowiedzi Janczenki.
Zamiast wziąć pierwszy adres IP z listy X_FORWARDED_FOR, biorę pierwszy, który nie jest znanym wewnętrznym adresem ip, ponieważ niektóre routery nie przestrzegają protokołu, i możesz zobaczyć wewnętrzny adres IP jako pierwszą wartość listy.
Mam nadzieję, że pomoże to innym pracownikom Google, którzy mają ten sam problem.
źródło
Oto krótki linijka, aby to osiągnąć:
źródło
Najprostszym rozwiązaniem (w przypadku korzystania z fastcgi + nignx) jest to, co komentowało itgorilla:
Ps: Dodałem tę odpowiedź, aby jego rozwiązanie było bardziej widoczne.
źródło
proxy_set_header REMOTE_ADDR $remote_addr;
nie łagodzi problemu po dodaniu do nginx.conf.Nigdy więcej zamieszania W najnowszych wersjach Django wyraźnie wspomniano, że adres IP klienta jest dostępny pod adresem
Aby uzyskać więcej informacji, sprawdź Dokumenty Django
źródło
W moim przypadku żadne z powyższych nie działa, więc muszę sprawdzić
uwsgi
+django
kod źródłowy i przekazać statyczny parametr w nginx i zobaczyć dlaczego / jak, a poniżej znajduje się to, co znalazłem.Informacje o środowisku:
wersja python : wersja
2.7.5
Django:
(1, 6, 6, 'final', 0)
wersja nginx:
nginx/1.6.0
uwsgi:
2.0.7
Informacje o ustawieniach env:
nginx jako nasłuch odwrotnego proxy w porcie
80
uwsgi jako gniazdo upstream unix, w końcu odpowie na żądanieInformacje o konfiguracji Django:
Konfiguracja nginx:
pobieranie wszystkich parametrów w aplikacji django:
Wniosek:
Zasadniczo musisz podać dokładnie tę samą nazwę pola / parametru w nginx i użyć
request.META[field/param]
w aplikacji django.Teraz możesz zdecydować, czy dodać oprogramowanie pośrednie (przechwytywacz), czy po prostu przeanalizować
HTTP_X_FORWARDED_FOR
niektóre widoki.źródło
Powodem, dla którego funkcja została pierwotnie usunięta z Django, był fakt, że nagłówkowi nie można ostatecznie zaufać. Powodem jest to, że łatwo jest sfałszować. Na przykład zalecanym sposobem skonfigurowania zwrotnego serwera proxy nginx jest:
Kiedy to zrobisz:
Twój nginx w myhost.com wyśle dalej:
The
X-Real-IP
Będzie IP pierwszego poprzedniego pełnomocnika, jeśli postępuj zgodnie z instrukcjami na ślepo.W przypadku problemów z zaufaniem do twoich użytkowników możesz spróbować czegoś takiego
django-xff
: https://pypi.python.org/pypi/django-xff/źródło
Brakowało mi również proxy w powyższej odpowiedzi. Użyłem
get_ip_address_from_request
z django_easy_timezones .A oto metoda
get_ip_address_from_request
zgodna z IPv4 i IPv6:źródło
W django.VERSION (2, 1, 1, „final”, 0) moduł obsługi żądań
jeśli zadzwonisz powyżej powyższego kodu dwa razy, możesz
AttributeError („Obiekt _” io.BytesIO ”nie ma atrybutu„ stream ””,)
AttributeError (obiekt „LimitedStream” nie ma atrybutu „raw” ”)
źródło