Ottieni l'indirizzo IP dei visitatori utilizzando Flask per Python


220

Sto realizzando un sito Web in cui gli utenti possono accedere e scaricare file, utilizzando il micro-framework Flask (basato su Werkzeug ) che utilizza Python (2.6 nel mio caso).

Ho bisogno di ottenere l'indirizzo IP degli utenti quando effettuano l'accesso (ai fini della registrazione). Qualcuno sa come fare questo? Sicuramente c'è un modo per farlo con Python?

Risposte:


295

Vedere la documentazione su come accedere all'oggetto Request e quindi ottenere dallo stesso oggetto Request, l'attributo remote_addr.

Esempio di codice

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

Per ulteriori informazioni, consultare la documentazione di Werkzeug .


1
Alcune volte può essere utile: request.access_route [0]
Jonathan Prates

46
Per quanto riguarda nginx, invia l'indirizzo IP reale sotto, HTTP_X_FORWARDED_FORquindi assicurati di non finire con localhost per ogni richiesta.
Rasty Turek,

95

I proxy possono renderlo un po 'complicato, assicurati di controllare ProxyFix ( documenti Flask ) se ne stai usando uno. Dai un'occhiata request.environnel tuo ambiente particolare. Con nginx a volte farò qualcosa del genere:

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

Quando i proxy, come nginx, inoltrano gli indirizzi, in genere includono l'IP originale da qualche parte nelle intestazioni della richiesta.

Aggiornamento Vedi l'implementazione di sicurezza del pallone . Ancora una volta, rivedere la documentazione su ProxyFix prima dell'implementazione. La tua soluzione può variare in base al tuo ambiente particolare.


2
Funziona quando si impostano i campi appropriati nella configurazione del proxy inverso. Utilizzato in produzione.
Drahnr,

3
@drahnr sì davvero. Il codice sopra funziona se ad es. Nginx si imposta: proxy_set_header X-Real-IP $ remote_addr;
Pors,

@pors - funziona. ho le stesse impostazioni nel mio conf nginx come te. ma ancora non capisco perché il codice: request.headers.get ('X-Real-IP', request.remote_addr) non funziona. Nota, intuitivamente otterrei il valore dalle intestazioni e userò il nome 'X-Real-IP' poiché è così che è la mia configurazione di nginx.
lostdorje,

82

In realtà, quello che troverai è che quando ottieni semplicemente quanto segue otterrai l'indirizzo del server:

request.remote_addr

Se si desidera l'indirizzo IP del client, utilizzare quanto segue:

request.environ['REMOTE_ADDR']

4
Solo se sei dietro un proxy inverso, no?
Ry-

3
@minitech Direi che al tuo codice non dovrebbe importare se sei dietro un proxy o no. Se questa opzione funziona in modo affidabile indipendentemente dal proxy inverso e l'altro presuppone che tu non sia dietro un proxy inverso, allora questo dovrebbe essere preferito. (Lo testerei se potessi facilmente impostare un proxy inverso, ma richiederebbe più tempo di quello che ho al momento.)
jpmc26

@ jpmc26: non vedo alcun motivo per cui dovrebbe funzionare affatto. request.remote_addrsuona come una proprietà che dovrebbe ottenere un indirizzo remoto a seconda che il proxy inverso sia attendibile.
Ry-

3
Utilizzando mod_wsgi, request.remote_addr ha restituito l'indirizzo del server ogni volta. request.environ ['REMOTE_ADDR'] mi ha fornito l'indirizzo IP pubblico del client. Forse mi manca qualcosa?
Chiedo,

@ jpmc26 Spesso devi preoccuparti se sei dietro un proxy remoto. In tal caso, l'IP che si connette a te sarà del server proxy remoto e dovrai fare affidamento sulle intestazioni aggiunte per ottenere l'IP client originale. In caso contrario , tali intestazioni in genere non saranno presenti e ti consigliamo di utilizzare l'IP di connessione come IP client. E non si può necessariamente solo controllare l'intestazione e ripiegare al IP di connessione se non è presente, perché poi se sei non è dietro un proxy inverso un client può falsificare il loro IP, che in molti casi sarà un problema di sicurezza .
Mark Amery,

28

L'indirizzo IP dell'utente può essere recuperato utilizzando il seguente frammento:

from flask import request
print(request.remote_addr)

3
Questo non è vero se l'app è in esecuzione dietro un server proxy come nginx . Che è spesso in produzione.
datashaman,

17

Ho Nginx e con sotto 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;
        }
}

La soluzione @ tirtha-r ha funzionato per me

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

La mia richiesta e risposta:

curl -X GET http://test.api

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

13

Il codice seguente fornisce sempre l'IP pubblico del client (e non un IP privato dietro un 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

Questa risposta insieme alla modifica della mia configurazione di nginx secondo questo blog ha funzionato per me. calvin.me/forward-ip-addresses-when-using-nginx-proxy
Romano Vacca

7

httpbin.org utilizza questo metodo:

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

Restituisce a 127.0.0.1causa di proxy, non molto utile.
Uri Goren,

3

Se si utilizza Nginx dietro altri servizi di bilanciamento, ad esempio AWS Application Balancer, HTTP_X_FORWARDED_FOR restituisce un elenco di indirizzi. Può essere risolto in questo modo:

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

Se si utilizza l'ambiente Gunicorn e Nginx, il seguente modello di codice funziona per te.

addr_ip4 = request.remote_addr

0

Questo dovrebbe fare il lavoro. Fornisce l'indirizzo IP del client (host remoto).

Si noti che questo codice è in esecuzione sul lato server.

from mod_python import apache

req.get_remote_host(apache.REMOTE_NOLOOKUP)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.