На самом деле, вы должны использовать управляемые объекты JVM или Spring-managed Object для вызова методов. из вашего вышеуказанного кода в классе контроллера вы создаете новый объект для вызова своего класса обслуживания, у которого есть объект с автоматической проводкой.
MileageFeeCalculator calc = new MileageFeeCalculator();
, поэтому он не будет работать таким образом.
Решение делает этот MileageFeeCalculator как объект с автоматической проводкой в самом контроллере.
Измените свой класс контроллера, как показано ниже.
@Controller
public class MileageFeeController {
@Autowired
MileageFeeCalculator calc;
@RequestMapping("/mileage/{miles}")
@ResponseBody
public float mileageFee(@PathVariable int miles) {
return calc.mileageCharge(miles);
}
}
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
Убедитесь, что вы настроили обратный прокси (если есть) (например, mod_rpaf
, установленный для Apache).
Примечание: в приведенном выше примере используется первый элемент в X-Forwarded-For
, но вы возможно, захотите использовать последний элемент (например, в случае Heroku: Получить реальный IP-адрес клиента на Heroku )
И затем просто передать запрос в качестве аргумента для него; / g3]
get_client_ip(request)
Я хотел бы предложить улучшение ответа яньченко.
Вместо того, чтобы принимать первый ip в списке X_FORWARDED_FOR, я беру первый, который не является известным внутренним ip, поскольку некоторые роутеры надевают ' t уважение к протоколу, и вы можете увидеть внутреннее ips как первое значение списка.
PRIVATE_IPS_PREFIX = ('10.', '172.', '192.', )
def get_client_ip(request):
"""get the client ip from the request
"""
remote_address = request.META.get('REMOTE_ADDR')
# set the default value of the ip to be the REMOTE_ADDR if available
# else None
ip = remote_address
# try to get the first non-proxy ip (not a private ip) from the
# HTTP_X_FORWARDED_FOR
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
if x_forwarded_for:
proxies = x_forwarded_for.split(',')
# remove the private ips from the beginning
while (len(proxies) > 0 and
proxies[0].startswith(PRIVATE_IPS_PREFIX)):
proxies.pop(0)
# take the first ip which is not a private one (of a proxy)
if len(proxies) > 0:
ip = proxies[0]
return ip
Надеюсь, это поможет собратьям Google, которые имеют ту же проблему.
Причина, по которой функциональность была удалена из Django изначально, заключалась в том, что заголовку нельзя доверять. Причина в том, что его легко обмануть. Например, рекомендуемый способ настройки обратного прокси nginx состоит в следующем:
add_header X-Forwarded-For $proxy_add_x_forwarded_for;
add_header X-Real-Ip $remote_addr;
Когда вы выполните:
curl -H 'X-Forwarded-For: 8.8.8.8, 192.168.1.2' http://192.168.1.3/
Ваш nginx в myhost.com отправит вперед:
X-Forwarded-For: 8.8.8.8, 192.168.1.2, 192.168.1.3
X-Real-IP
будет IP-адресом первого предыдущего прокси-сервера, если вы будете следовать инструкциям вслепую.
В случае, если доверять тому, кто является вашим пользователем, вы можете попробовать что-то например django-xff
: https://pypi.python.org/pypi/django-xff/
Самое простое решение (в случае использования fastcgi + nignx) - это то, что он ответил:
Спасибо за этот замечательный вопрос. Мой fastcgi не передавал мета-ключ REMOTE_ADDR. Я добавил строку ниже в nginx.conf и исправил проблему: fastcgi_param REMOTE_ADDR $ remote_addr; - itgorilla
blockquote>Ps: Я добавил этот ответ, чтобы сделать его решение более заметным.
proxy_set_header REMOTE_ADDR $remote_addr;
не устраняет проблему при добавлении в nginx.conf.
– Hassan Baig
13 December 2015 в 11:58
Я также пропустил прокси в ответе выше. Я использовал get_ip_address_from_request
из django_easy_timezones .
from easy_timezones.utils import get_ip_address_from_request, is_valid_ip, is_local_ip
ip = get_ip_address_from_request(request)
try:
if is_valid_ip(ip):
geoip_record = IpRange.objects.by_ip(ip)
except IpRange.DoesNotExist:
return None
И вот метод get_ip_address_from_request
, IPv4 и IPv6 готовы:
def get_ip_address_from_request(request):
""" Makes the best attempt to get the client's real IP or return the loopback """
PRIVATE_IPS_PREFIX = ('10.', '172.', '192.', '127.')
ip_address = ''
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR', '')
if x_forwarded_for and ',' not in x_forwarded_for:
if not x_forwarded_for.startswith(PRIVATE_IPS_PREFIX) and is_valid_ip(x_forwarded_for):
ip_address = x_forwarded_for.strip()
else:
ips = [ip.strip() for ip in x_forwarded_for.split(',')]
for ip in ips:
if ip.startswith(PRIVATE_IPS_PREFIX):
continue
elif not is_valid_ip(ip):
continue
else:
ip_address = ip
break
if not ip_address:
x_real_ip = request.META.get('HTTP_X_REAL_IP', '')
if x_real_ip:
if not x_real_ip.startswith(PRIVATE_IPS_PREFIX) and is_valid_ip(x_real_ip):
ip_address = x_real_ip.strip()
if not ip_address:
remote_addr = request.META.get('REMOTE_ADDR', '')
if remote_addr:
if not remote_addr.startswith(PRIVATE_IPS_PREFIX) and is_valid_ip(remote_addr):
ip_address = remote_addr.strip()
if not ip_address:
ip_address = '127.0.0.1'
return ip_address
здесь короткий короткий лайнер для выполнения этого:
request.META.get('HTTP_X_FORWARDED_FOR', request.META.get('REMOTE_ADDR')).split(',')[-1].strip()
В моем случае ничего из этого не работает, поэтому я должен проверить исходный код uwsgi
+ django
и передать статический параметр в nginx и посмотреть, почему / как, а ниже - то, что я нашел.
Env info: версия python: 2.7.5
версия Django: (1, 6, 6, 'final', 0)
версия nginx: nginx/1.6.0
uwsgi: 2.0.7
Информация о настройке Env: nginx как обратный прокси-сервер, прослушивающий порт 80
uwsgi как upstream unix socket, будет отвечать на запрос в конце концов
Информация о конфигурации Django:
USE_X_FORWARDED_HOST = True # with or without this line does not matter
nginx config:
uwsgi_param X-Real-IP $remote_addr;
// uwsgi_param X-Forwarded-For $proxy_add_x_forwarded_for;
// uwsgi_param HTTP_X_FORWARDED_FOR $proxy_add_x_forwarded_for;
// hardcode for testing
uwsgi_param X-Forwarded-For "10.10.10.10";
uwsgi_param HTTP_X_FORWARDED_FOR "20.20.20.20";
получает все параметры в django app:
X-Forwarded-For : 10.10.10.10
HTTP_X_FORWARDED_FOR : 20.20.20.20
Заключение:
Итак, вы должны указать точно такое же имя поля / параметра в nginx и использовать request.META[field/param]
в приложении django.
И теперь вы можете решить, следует ли добавлять промежуточное программное обеспечение (перехватчик) или просто анализировать HTTP_X_FORWARDED_FOR
в определенных представлениях.
Самое простое решение этого:
from ipaddress import ip_address
, а затем использовать его как:
print(get_client_ip(request))
Ответ Alexander замечательный, но не хватает обработки прокси, которые иногда возвращают несколько IP-адресов в заголовок HTTP_X_FORWARDED_FOR.
Реальный IP обычно находится в конце списка, как описано здесь: http://en.wikipedia.org/wiki/X-Forwarded-For
Решение представляет собой простую модификацию кода Александра:
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
request.META
, я включаю значение по умолчанию, поскольку заголовки часто меняются: request.META.get('REMOTE_ADDR', None)
– Carl G
14 July 2012 в 06:28
Вы можете использовать django-ipware , который поддерживает Python 2 & amp; 3 и обрабатывает IPv4 & amp; IPv6.
Установить:
pip install django-ipware
blockquote> blockquote>Простое использование:
Чтобы получить IP-адрес клиента.
blockquote> blockquote># 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)
Расширенное использование:
Пользовательский заголовок - Пользовательский заголовок запроса для ipware для просмотра
blockquote> blockquote>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'])
Количество прокси-серверов - сервер Django находится за фиксированным числом прокси-серверов
blockquote> blockquote>i, r = get_client_ip(request, proxy_count=1)
Доверенные прокси - сервер Django находится за одним или несколькими известными & amp; доверенные прокси
blockquote> blockquote>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.'))
IPWARE_META_PRECEDENCE_LIST
в используемую вами переменную или используйте альтернативу, например pypi.python.org/pypi/WsgiUnproxy
– vdboor
30 November 2015 в 12:28
ip = get_client_ip(request)
в своей функции просмотра. – yanchenko 3 January 2011 в 08:38X-Forwarded-For: client, proxy1, proxy2
. Таким образом, первый адрес - клиентский. – Michael Waterfall 16 February 2014 в 11:36