How do I get user's IP in django?
I have a view like this:
# 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())
But I get this error:
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
In my case none of above works, so I have to check
uwsgi
+django
source code and pass static param in nginx and see why/how, and below is what I have found.Env info:
python version:
2.7.5
Django version:
(1, 6, 6, 'final', 0)
nginx version:
nginx/1.6.0
uwsgi:
2.0.7
Env setting info:
nginx as reverse proxy listening at port
80
uwsgi as upstream unix socket, will response to the request eventuallyDjango config info:
nginx config:
getting all the params in django app:
Conclusion:
So basically, you have to specify exactly the same field/param name in nginx, and use
request.META[field/param]
in django app.And now you can decide whether to add a middleware (interceptor) or just parse
HTTP_X_FORWARDED_FOR
in certain views.Alexander's answer is great, but lacks the handling of proxies that sometimes return multiple IP's in the HTTP_X_FORWARDED_FOR header.
The real IP is usually at the end of the list, as explained here: http://en.wikipedia.org/wiki/X-Forwarded-For
The solution is a simple modification of Alexander's code:
The reason the functionality was removed from Django originally was that the header cannot ultimately be trusted. The reason is that it is easy to spoof. For example the recommended way to configure an nginx reverse proxy is to:
When you do:
Your nginx in myhost.com will send onwards:
The
X-Real-IP
will be the IP of the first previous proxy if you follow the instructions blindly.In case trusting who your users are is an issue, you could try something like
django-xff
: https://pypi.python.org/pypi/django-xff/I was also missing proxy in above answer. I used
get_ip_address_from_request
from django_easy_timezones.And here is method
get_ip_address_from_request
, IPv4 and IPv6 ready:The most easy solution to this is:
and then use it like:
here is a short one liner to accomplish this: