Explain Codes LogoExplain Codes Logo

Get IP address of visitors using Flask for Python

python
proxy-engineering
flask
ip-address
Anton ShumikhinbyAnton Shumikhin·Feb 8, 2025
TLDR

To quickly get a visitor's IP in Flask, refer to the request.remote_addr attribute:

from flask import Flask, request app = Flask(__name__) @app.route('/') def show_ip(): return 'Your IP: ' + request.remote_addr

In a proxy setup, the X-Forwarded-For header holds the real IP:

from flask import request real_ip = request.headers.get('X-Forwarded-For', request.remote_addr)

Tricky Proxies and the 'X-Real-IP' Conundrum

If you have deployed your Flask application behind a reverse proxy, you may find that the request.remote_addr attribute carries the proxy's IP, not the client's. In such scenarios, proxies typically pass on the original IP in the HTTP headers X-Forwarded-For or X-Real-IP. Ways to mitigate this include the ProxyFix method or manual header parsing:

from werkzeug.middleware.proxy_fix import ProxyFix app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1, x_host=1)

Alternatively:

from flask import Flask, request app = Flask(__name__) @app.route('/') def show_real_ip(): if 'X-Real-IP' in request.headers: real_ip = request.headers['X-Real-IP'] else: real_ip = request.remote_addr return 'Your real IP: ' + real_ip

To check the correctness of your IP retrieval, unleash the power of curl:

curl http://localhost:5000/

Comment: "It's test time!"

Tackling Multiple Proxies and a Forest of IP addresses

Hosting environments often see incoming requests hooping through multiple proxies. In such scenarios, the X-Forwarded-For header will host a list of IP addresses, separated by commas, with the first one typically being the client's.

x_forwarded_for = request.headers.get('X-Forwarded-For', '').split(',') client_ip = x_forwarded_for[0] if x_forwarded_for else request.remote_addr

Remember, while dealing with IP addresses, it's not all rose-colored glasses. Be cloud-ready for some vulnerabilities, like the possibility of IP spoofing. An attacker can forge the X-Forwarded-For and trusting it without validation could lead to cybersecurity issues.

Nginx Logging Protocol

If Nginx is your reverse proxy of choice, ensure it's accurately logging client IPs by making the proper configurations:

location / {
    proxy_pass http://your_flask_app;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

and voila, it will now pass the client's IP address in the appropriate headers.

For Smooth Sailing during Local Development

During application development, remember to serve your Flask app with:

app.run(debug=True, host='0.0.0.0', port=5000)

Note that debug=True provides live reloading and also takes a serious shot at generating the most useful error messages!

Securing IPs with a Flask of Fine Security

Flask extensions like flask-security can beef up your application with robust control over IP logging and handling.

from flask_security import Security, SQLAlchemyUserDatastore, UserMixin, RoleMixin # Insert your models for users and roles including IP logging here... security = Security(app, user_datastore)

This snippet could serve as your maiden foray into integrating flask-security into your application.