Erhalten Sie die IP-Adresse von Besuchern mit Flask for Python

220

Ich erstelle eine Website, auf der sich Benutzer anmelden und Dateien herunterladen können, indem ich das Flask Micro-Framework (basierend auf Werkzeug ) verwende, das Python verwendet (in meinem Fall 2.6).

Ich muss die IP-Adresse der Benutzer abrufen, wenn sie sich anmelden (zu Protokollierungszwecken). Weiß jemand, wie man das macht? Sicher gibt es eine Möglichkeit, dies mit Python zu tun?

Jon Cox
quelle

Antworten:

295

Weitere Informationen finden Sie in der Dokumentation zum Zugriff auf das Anforderungsobjekt und zum Abrufen des Attributs von demselben Anforderungsobjekt remote_addr.

Codebeispiel

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

Weitere Informationen finden Sie in der Werkzeug-Dokumentation .

Tarantel
quelle
1
Manchmal kann es nützlich sein: request.access_route [0]
Jonathan Prates
46
Nginx sendet die echte IP-Adresse unter HTTP_X_FORWARDED_FOR, stellen Sie also sicher, dass Sie nicht bei jeder Anforderung mit localhost enden.
Rasty Turek
95

Proxies können dies etwas schwierig machen. Lesen Sie unbedingt ProxyFix ( Flask-Dokumente ), wenn Sie eines verwenden. Schauen Sie sich request.environIhre spezielle Umgebung an. Mit Nginx mache ich manchmal so etwas:

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

Wenn Proxys wie Nginx Adressen weiterleiten, enthalten sie normalerweise die ursprüngliche IP-Adresse irgendwo in den Anforderungsheadern.

Update Siehe die Implementierung der Flaschensicherheit . Lesen Sie vor der Implementierung erneut die Dokumentation zu ProxyFix. Ihre Lösung kann je nach Umgebung variieren.

Stephen Fuhry
quelle
2
Dies funktioniert, wenn Sie die entsprechenden Felder in der Konfiguration Ihres Reverse-Proxys festlegen. Wird in der Produktion verwendet.
Drahnr
3
@rahnr ja in der Tat. Der obige Code funktioniert, wenn Sie beispielsweise in nginx Folgendes festlegen: proxy_set_header X-Real-IP $ remote_addr;
Pors
@pors - es funktioniert. Ich habe die gleichen Einstellungen in meinem Nginx Conf wie Sie. aber ich verstehe immer noch nicht, warum der Code: request.headers.get ('X-Real-IP', request.remote_addr) nicht funktioniert. Beachten Sie, dass ich intuitiv den Wert aus den Headern abrufen und den Namen 'X-Real-IP' verwenden würde, da meine nginx conf so ist.
lostdorje
82

Tatsächlich werden Sie feststellen, dass Sie die Adresse des Servers erhalten, wenn Sie einfach Folgendes erhalten:

request.remote_addr

Wenn Sie die IP-Adresse des Clients möchten, verwenden Sie Folgendes:

request.environ['REMOTE_ADDR']
Chiedo
quelle
4
Nur wenn Sie hinter einem Reverse Proxy stehen, nein?
Ry-
3
@minitech Ich würde sagen, dass es Ihrem Code egal sein sollte, ob Sie hinter einem Proxy stehen oder nicht. Wenn diese Option unabhängig vom Reverse-Proxy zuverlässig funktioniert und die andere davon ausgeht, dass Sie nicht hinter einem Reverse-Proxy stehen, sollte dies bevorzugt werden. (Ich würde dies testen, wenn ich leicht einen Reverse-Proxy einrichten könnte, aber das würde mehr Zeit in
Anspruch
@ jpmc26: Ich sehe keinen Grund, warum es überhaupt funktionieren sollte. request.remote_addrklingt wie eine Eigenschaft, die eine Remote-Adresse erhalten sollte, je nachdem, ob der Reverse-Proxy vertrauenswürdig ist.
Ry-
3
Mit mod_wsgi hat request.remote_addr jedes Mal die Serveradresse zurückgegeben. request.environ ['REMOTE_ADDR'] hat mir die öffentliche IP-Adresse des Clients gegeben. Vielleicht fehlt mir etwas?
Chiedo
@ jpmc26 Sie häufig tun Notwendigkeit, egal , ob Sie sich hinter einem Remote - Proxy sind. Wenn dies der Fall ist, handelt es sich bei der IP-Adresse, die eine Verbindung zu Ihnen herstellt, um den Remote-Proxyserver, und Sie müssen sich auf die hinzugefügten Header verlassen, um die ursprüngliche Client-IP zu erhalten. Wenn Sie nicht , werden diese Header der Regel nicht vorhanden sein, und Sie werden die IP - Verbindung als Client - IP verwenden möchten. Und Sie können nicht unbedingt einfach nach dem Header suchen und auf die Verbindungs-IP zurückgreifen, wenn diese nicht vorhanden ist. Wenn Sie sich nicht hinter einem Reverse-Proxy befinden, kann ein Client seine IP-Adresse fälschen, was unter vielen Umständen ein Sicherheitsproblem darstellt .
Mark Amery
28

Die IP-Adresse des Benutzers kann mit dem folgenden Snippet abgerufen werden:

from flask import request
print(request.remote_addr)
Davidg
quelle
3
Dies gilt nicht, wenn die App hinter einem Proxyserver wie nginx ausgeführt wird . Was es oft in Produktion ist.
Datashaman
17

Ich habe Nginx und mit unten Nginx Config :

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 Lösung hat bei mir funktioniert

#!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)

Meine Anfrage und Antwort:

curl -X GET http://test.api

{
    "ip": "Client Ip......"
}
Soli
quelle
13

Der folgende Code gibt immer die öffentliche IP des Clients an (und keine private IP hinter einem Proxy).

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
Tirtha R.
quelle
Diese Antwort zusammen mit der Änderung meiner Nginx-Konfiguration gemäß diesem Blog hat für mich funktioniert. calvin.me/forward-ip-addresses-when-using-nginx-proxy
Romano Vacca
7

httpbin.org verwendet diese Methode:

return jsonify(origin=request.headers.get('X-Forwarded-For', request.remote_addr))
Pegasus
quelle
Rückgabe 127.0.0.1aufgrund von Proxy, nicht sehr hilfreich.
Uri Goren
3

Wenn Sie Nginx hinter einem anderen Balancer verwenden, z. B. AWS Application Balancer, gibt HTTP_X_FORWARDED_FOR eine Adressliste zurück. Es kann so behoben werden:

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
Vlad
quelle
1

Wenn Sie die Gunicorn- und Nginx-Umgebung verwenden, funktioniert die folgende Codevorlage für Sie.

addr_ip4 = request.remote_addr
Jyotiprakash panigrahi
quelle
0

Dies sollte den Job machen. Es gibt die Client-IP-Adresse (Remote-Host) an.

Beachten Sie, dass dieser Code auf der Serverseite ausgeführt wird.

from mod_python import apache

req.get_remote_host(apache.REMOTE_NOLOOKUP)
Raviv
quelle