Как я могу получить IP пользователя в Django?
У меня есть такой вид:
# 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())
Но я получаю эту ошибку:
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
Ответы:
Убедитесь, что у вас настроен обратный прокси (если есть), настроенный правильно (например,
mod_rpaf
установлен для Apache).Примечание: в приведенном выше примере используется первый элемент
X-Forwarded-For
, но вы можете использовать последний элемент (например, в случае Heroku: получить реальный IP-адрес клиента в Heroku )А затем просто передайте запрос в качестве аргумента;
источник
ip = get_client_ip(request)
в вашей функции просмотра.X-Forwarded-For: client, proxy1, proxy2
. Итак, первый адрес - адрес клиента.Вы можете использовать django-ipware, который поддерживает Python 2 & 3 и обрабатывает IPv4 и IPv6 .
Установка:
pip install django-ipware
Простое использование:
Расширенное использование:
Пользовательский заголовок - Пользовательский заголовок запроса для ipware, чтобы посмотреть:
Число прокси - сервер Django находится за фиксированным количеством прокси:
Доверенные прокси - сервер Django находится за одним или несколькими известными и доверенными прокси:
Примечание: прочитайте это уведомление .
источник
IPWARE_META_PRECEDENCE_LIST
переменную, которую вы используете, или используйте альтернативу, такую как pypi.python.org/pypi/WsgiUnproxyget_client_ip()
.get_real_ip
устарела и будет удалена в 3.0.Ответ Александра великолепен, но ему не хватает обработки прокси, которые иногда возвращают несколько IP-адресов в заголовке HTTP_X_FORWARDED_FOR.
Реальный IP обычно находится в конце списка, как описано здесь: http://en.wikipedia.org/wiki/X-Forwarded-For
Решение представляет собой простую модификацию кода Александра:
источник
request.META
меня, я включаю значение по умолчанию, так как заголовки часто пропадают:request.META.get('REMOTE_ADDR', None)
Я хотел бы предложить улучшение ответа Янченко.
Вместо того, чтобы брать первый ip в списке X_FORWARDED_FOR, я беру первый, который не известен как внутренний ip, так как некоторые маршрутизаторы не уважают протокол, и вы можете видеть внутренние ips как первое значение списка.
Надеюсь, это поможет коллегам-гуглерам, у которых возникла такая же проблема.
источник
Вот короткий вкладыш для этого:
источник
Самое простое решение (если вы используете fastcgi + nignx) - это то, что itgorilla прокомментировала:
PS: я добавил этот ответ только для того, чтобы сделать его решение более заметным.
источник
proxy_set_header REMOTE_ADDR $remote_addr;
не облегчает проблему при добавлении в nginx.conf.Больше нет путаницы В последних версиях Django четко указано, что IP-адрес клиента доступен по адресу
для получения дополнительной информации проверьте Django Docs
источник
В моем случае ничего из вышеперечисленного не работает, поэтому я должен проверить
uwsgi
+django
исходный код и передать статический параметр в nginx и посмотреть, почему / как, а ниже - то, что я нашел.Информация env:
версия python : версия
2.7.5
Django:
(1, 6, 6, 'final', 0)
версия nginx:
nginx/1.6.0
uwsgi:
2.0.7
Информация настройки Env:
nginx как обратный прокси-сервер, прослушивающий порт
80
uwsgi как восходящий сокет unix, в конечном итоге ответит на запросИнформация о конфигурации Django:
Конфигурация nginx:
получить все параметры в приложении django:
Вывод:
Таким образом, в основном, вы должны указать точно такое же имя поля / параметра в nginx и использовать
request.META[field/param]
в приложении django.И теперь вы можете решить, добавлять ли промежуточное программное обеспечение (перехватчик) или просто анализировать
HTTP_X_FORWARDED_FOR
определенные представления.источник
Первоначальная причина, по которой функциональность была удалена из Django, заключалась в том, что заголовок в конечном итоге нельзя доверять. Причина в том, что это легко подделать. Например, рекомендуемый способ настройки обратного прокси-сервера nginx:
Когда вы делаете:
Ваш nginx на myhost.com отправит дальше:
X-Real-IP
Будет IP первого предыдущего прокси - сервера , если вы будете следовать инструкциям вслепую.В случае, если проблема заключается в том, чтобы доверять своим пользователям, вы можете попробовать что-то вроде
django-xff
: https://pypi.python.org/pypi/django-xff/источник
Мне также не хватало прокси в ответе выше. Я использовал
get_ip_address_from_request
от django_easy_timezones .И вот метод
get_ip_address_from_request
, IPv4 и IPv6 готовы:источник
В django.VERSION (2, 1, 1, 'final', 0) обработчик запросов
если вы позвоните по вышеуказанному коду дважды, вы можете получить
AttributeError («Объект« _io.BytesIO »не имеет атрибута« поток »»,)
AttributeError («Объект« LimitedStream »не имеет атрибута« raw »»)
источник