Bagaimana cara saya mendapatkan IP pengguna di Django?
Saya memiliki pandangan seperti ini:
# 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())
Tapi saya mendapatkan kesalahan ini:
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
Jawaban:
Pastikan Anda memiliki proxy terbalik (jika ada) yang dikonfigurasi dengan benar (mis.
mod_rpaf
Diinstal untuk Apache).Catatan: di atas menggunakan item pertama
X-Forwarded-For
, tetapi Anda mungkin ingin menggunakan item terakhir (misalnya, dalam kasus Heroku: Dapatkan alamat IP asli klien di Heroku )Dan kemudian hanya meneruskan permintaan sebagai argumen padanya;
sumber
ip = get_client_ip(request)
fungsi tampilan Anda.X-Forwarded-For: client, proxy1, proxy2
. Jadi alamat pertama adalah milik klien.Anda dapat menggunakan django-ipware yang mendukung Python 2 & 3 dan menangani IPv4 & IPv6 .
Install:
pip install django-ipware
Penggunaan Sederhana:
Penggunaan Lanjutan:
Header Kustom - Header permintaan kustom untuk ipware untuk dilihat:
Proxy Count - server Django ada di belakang sejumlah proxy:
Proxy Tepercaya - Server Django ada di belakang satu atau lebih proksi yang diketahui & tepercaya:
Catatan: baca pemberitahuan ini .
sumber
IPWARE_META_PRECEDENCE_LIST
ke variabel yang Anda gunakan, atau gunakan alternatif seperti pypi.python.org/pypi/WsgiUnproxyget_client_ip()
.get_real_ip
sudah usang dan akan dihapus dalam 3.0.Jawaban Alexander bagus, tetapi tidak memiliki penanganan proxy yang terkadang mengembalikan beberapa IP di header HTTP_X_FORWARDED_FOR.
IP asli biasanya ada di akhir daftar, seperti dijelaskan di sini: http://en.wikipedia.org/wiki/X-Forwarded-For
Solusinya adalah modifikasi sederhana dari kode Alexander:
sumber
request.META
saya sertakan nilai default karena header sering salah:request.META.get('REMOTE_ADDR', None)
Saya ingin menyarankan peningkatan jawaban yanchenko.
Alih-alih mengambil ip pertama dalam daftar X_FORWARDED_FOR, saya mengambil ip pertama yang bukan ip internal yang dikenal, karena beberapa router tidak menghormati protokol, dan Anda dapat melihat ips internal sebagai nilai pertama dari daftar.
Saya harap ini membantu sesama Google yang memiliki masalah yang sama.
sumber
di sini adalah liner pendek untuk mencapai ini:
sumber
Solusi paling sederhana (jika Anda menggunakan fastcgi + nignx) adalah komentar itgorilla:
PS: Saya menambahkan jawaban ini hanya untuk membuat solusinya lebih terlihat.
sumber
proxy_set_header REMOTE_ADDR $remote_addr;
tidak mengurangi masalah ketika ditambahkan ke nginx.conf.Tidak Ada lagi kebingungan Dalam versi terbaru Django disebutkan dengan jelas bahwa alamat IP klien tersedia di
untuk info lebih lanjut, periksa Django Docs
sumber
Dalam kasus saya tidak ada yang bekerja di atas, jadi saya harus memeriksa kode sumber
uwsgi
+django
dan melewatkan param statis di nginx dan melihat mengapa / bagaimana, dan di bawah ini adalah apa yang saya temukan.Info Env:
versi python : Versi
2.7.5
Django:
(1, 6, 6, 'final', 0)
versi nginx:
nginx/1.6.0
uwsgi:
2.0.7
Env pengaturan info:
nginx sebagai reverse proxy listening di port
80
uwsgi sebagai hulu unix socket, akan merespons permintaan pada akhirnyaInfo konfigurasi Django:
konfigurasi nginx:
mendapatkan semua params di aplikasi Django:
Kesimpulan:
Jadi pada dasarnya, Anda harus menentukan bidang / nama param yang sama persis di nginx, dan menggunakannya
request.META[field/param]
di aplikasi Django.Dan sekarang Anda dapat memutuskan apakah akan menambahkan middleware (interseptor) atau hanya menguraikan
HTTP_X_FORWARDED_FOR
dalam pandangan tertentu.sumber
Alasan fungsionalitas dihapus dari Django awalnya adalah bahwa header pada akhirnya tidak dapat dipercaya. Alasannya adalah bahwa itu mudah untuk dipalsukan. Misalnya, cara yang disarankan untuk mengonfigurasi proxy terbalik nginx adalah dengan:
Saat kamu melakukan:
Nginx Anda di myhost.com akan mengirimkan seterusnya:
Ini
X-Real-IP
akan menjadi IP dari proksi sebelumnya pertama jika Anda mengikuti instruksi secara membabi buta.Jika mempercayai siapa pengguna Anda merupakan masalah, Anda dapat mencoba sesuatu seperti
django-xff
: https://pypi.python.org/pypi/django-xff/sumber
Saya juga kehilangan proxy di jawaban di atas. Saya menggunakan
get_ip_address_from_request
dari django_easy_timezones .Dan berikut adalah metode
get_ip_address_from_request
, IPv4 dan IPv6 siap:sumber
Dalam django.VERSION (2, 1, 1, 'final', 0) request handler
jika Anda memanggil kode di atas dua kali, Anda mungkin mendapatkannya
AttributeError ("'_ io.BytesIO' objek tidak memiliki atribut 'stream'",)
AttributeError ("objek 'LimitedStream' tidak memiliki atribut 'raw'")
sumber