Plashon için Flask kullanarak ziyaretçilerin IP adresini alın


221

Kullanıcıların Python (benim durumumda 2.6) kullanan Flask mikro çerçevesini ( Werkzeug tabanlı ) kullanarak, oturum açıp dosyaları indirebilecekleri bir web sitesi yapıyorum .

Oturum açarken kullanıcıların IP adresini almam gerekiyor (giriş için). Bunu nasıl yapacağını bilen var mı? Kesinlikle Python ile yapmanın bir yolu var mı?

Yanıtlar:


296

Request nesnesine nasıl erişeceğinize ve daha sonra aynı Request nesnesinden, niteliğe nasıl ulaşacağınıza ilişkin belgelere bakın remote_addr.

Kod örneği

from flask import request
from flask import jsonify

@app.route("/get_my_ip", methods=["GET"])
def get_my_ip():
    return jsonify({'ip': request.remote_addr}), 200

Daha fazla bilgi için Werkzeug belgelerine bakın .


1
Bazı durumlarda yararlı olabilir: request.access_route [0]
Jonathan Prates

46
Nginx'e gelince, gerçek IP adresini altında gönderir, bu HTTP_X_FORWARDED_FORnedenle her istek için localhost ile sonuçlanmadığınızdan emin olun.
Rasty Turek

95

Proxy'ler bunu biraz zorlaştırabilir , kullanıyorsanız ProxyFix'e ( Flask belgeleri ) baktığınızdan emin olun . Kendi request.environortamınıza bir göz atın . Nginx ile bazen böyle bir şey yapacağım:

from flask import request   
request.environ.get('HTTP_X_REAL_IP', request.remote_addr)   

Nginx, yönlendirme adresleri gibi proxy'ler genellikle istek başlıklarında bir yerlerde orijinal IP'yi içerir.

Güncelleme Şişe güvenlik uygulamasına bakın . Tekrar uygulamadan önce ProxyFix ile ilgili belgeleri gözden geçirin. Çözümünüz, bulunduğunuz ortama bağlı olarak değişebilir.


2
Bu, ters proxy'nizin yapılandırmasında uygun alanları ayarladığınızda çalışır. Üretimde kullanılır.
drahnr

3
@drahnr evet gerçekten. Yukarıdaki kod örneğin nginx'te ayarladıysanız çalışır: proxy_set_header X-Real-IP $ remote_addr;
pors

@pors - işe yarıyor. seninle aynı ayarlarım var. ama yine de neden kodu anlamıyorum: request.headers.get ('X-Real-IP', request.remote_addr) çalışmıyor. Not, sezgisel olarak ben üstbilgilerden değer almak ve benim nginx conf böyle 'X-Real-IP' adını kullanmak istiyorum.
lostdorje

82

Aslında, sadece aşağıdakileri elde ettiğinizde sunucunun adresini alacağınız şey bulacaktır:

request.remote_addr

İstemcilerin IP adresini istiyorsanız, aşağıdakileri kullanın:

request.environ['REMOTE_ADDR']

4
Sadece ters bir proxy'nin arkasındaysanız, değil mi?
Ry-

3
@minitech Kodunuzun bir proxy'nin arkasında olup olmadığınızı umursamaması gerektiğini söyleyebilirim. Bu seçenek ters proxy'den bağımsız olarak güvenilir şekilde çalışırsa ve diğeri ters proxy'nin arkasında olmadığınızı varsayarsa, bu tercih edilmelidir. (Kolayca bir ters proxy kurabilirsem bunu test ederdim, ama şu anda sahip olduğumdan daha fazla zaman alacaktı.)
jpmc26

@ jpmc26: Hiç çalışmaması için hiçbir neden göremiyorum. request.remote_addrters proxy'ye güvenilip güvenilmediğine bağlı olarak uzak adres alması gereken bir özellik gibi görünür.
Ry-

3
Mod_wsgi kullanarak request.remote_addr sunucuların adresini her seferinde döndürdü. request.environ ['REMOTE_ADDR'] bana müşterinin genel IP adresini aldı. Belki bir şey eksik?
Chiedo

@ jpmc26 Sık yapmak Uzak Proxy'yle iseniz bakım ihtiyacını. Eğer öyleyse, size bağlanan IP uzak proxy sunucusundan olacaktır ve orijinal istemci IP'sini almak için eklediği başlıklara güvenmeniz gerekir. Eğer konum değil , bu başlıklar tipik olarak mevcut olmayacak ve istemci IP olarak bağlantı IP kullanmak isteyeceksiniz. Sen o zaman çünkü eğer Ve mutlaka sadece başlığının denetlemek ve mevcut değilse bağlantı IP'ye geri düşemez değil bir ters proxy arkasında bir istemci bir güvenlik sorunu olacak birçok durumda onların IP, aldatabilir .
Mark Amery

28

Kullanıcının IP adresi aşağıdaki snippet kullanılarak alınabilir:

from flask import request
print(request.remote_addr)

3
Uygulama nginx gibi bir proxy sunucunun arkasında çalışıyorsa bu doğru değildir . Hangi sıklıkla üretimde olduğunu.
datashaman

17

Ben Nginx ve aşağıdaki Nginx Config ile :

server {
    listen 80;
    server_name xxxxxx;
    location / {
               proxy_set_header   Host                 $host;
               proxy_set_header   X-Real-IP            $remote_addr;
               proxy_set_header   X-Forwarded-For      $proxy_add_x_forwarded_for;
               proxy_set_header   X-Forwarded-Proto    $scheme;

               proxy_pass http://x.x.x.x:8000;
        }
}

@ tirtha-r çözümü benim için çalıştı

#!flask/bin/python
from flask import Flask, jsonify, request
app = Flask(__name__)

@app.route('/', methods=['GET'])
def get_tasks():
    if request.environ.get('HTTP_X_FORWARDED_FOR') is None:
        return jsonify({'ip': request.environ['REMOTE_ADDR']}), 200
    else:
        return jsonify({'ip': request.environ['HTTP_X_FORWARDED_FOR']}), 200

if __name__ == '__main__':
    app.run(debug=True,host='0.0.0.0', port=8000)

İsteğim ve Yanıtım:

curl -X GET http://test.api

{
    "ip": "Client Ip......"
}

13

Aşağıdaki kod her zaman istemcinin genel IP'sini verir (proxy'nin arkasında özel bir IP değil).

from flask import request

if request.environ.get('HTTP_X_FORWARDED_FOR') is None:
    print(request.environ['REMOTE_ADDR'])
else:
    print(request.environ['HTTP_X_FORWARDED_FOR']) # if behind a proxy

Bu cevabı nginx yapılandırmamı bu bloga göre değiştirmekle birlikte benim için çalıştı. calvin.me/forward-ip-addresses-when-using-nginx-proxy
Romano Vacca

7

httpbin.org bu yöntemi kullanır:

return jsonify(origin=request.headers.get('X-Forwarded-For', request.remote_addr))

İade 127.0.0.1nedeniyle proxy, çok yararlı değil.
Uri Goren

3

Nginx'i AWS Uygulama Dengeleyici gibi diğer dengeleyicilerin arkasında kullanırsanız, HTTP_X_FORWARDED_FOR adres listesini döndürür. Bu şekilde sabitlenebilir:

if 'X-Forwarded-For' in request.headers:
    proxy_data = request.headers['X-Forwarded-For']
    ip_list = proxy_data.split(',')
    user_ip = ip_list[0]  # first address in list is User IP
else:
    user_ip = request.remote_addr  # For local development

1

Gunicorn ve Nginx ortamını kullanıyorsanız, aşağıdaki kod şablonu sizin için çalışır.

addr_ip4 = request.remote_addr

0

Bu işi yapmalı. İstemcinin IP adresini (uzak ana bilgisayar) sağlar.

Bu kodun sunucu tarafında çalıştığını unutmayın.

from mod_python import apache

req.get_remote_host(apache.REMOTE_NOLOOKUP)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.