Each Answer to this Q is separated by one/two green lines.
I just deployed a Flask app on Webfaction and I’ve noticed that
request.remote_addr is always
127.0.0.1. which is of course isn’t of much use.
How can I get the real IP address of the user in Flask on Webfaction?
If there is a proxy in front of Flask, then something like this will get the real IP in Flask:
if request.headers.getlist("X-Forwarded-For"): ip = request.headers.getlist("X-Forwarded-For") else: ip = request.remote_addr
Update: Very good point mentioned by Eli in his comment. There could be some security issues if you just simply use this. Read Eli’s post to get more details.
Flask’s documentation is pretty specific about recommended reverse proxy server setup:
If you deploy your application using one of these [WSGI] servers behind an HTTP [reverse] proxy you will need to rewrite a few headers in order for the application to work [properly]. The two problematic values in the WSGI environment usually are
HTTP_HOST… Werkzeug ships a fixer that will solve some common setups, but you might want to write your own WSGI middleware for specific setups.
And also about security consideration:
Please keep in mind that it is a security issue to use such a middleware in a non-proxy setup because it will blindly trust the incoming headers which might be forged by malicious clients.
The suggested code (that installs the middleware) that will make
request.remote_addr return client IP address is:
from werkzeug.contrib.fixers import ProxyFix app.wsgi_app = ProxyFix(app.wsgi_app, num_proxies=1)
num_proxies which is
1 by default. It’s the number of proxy servers in front of the app.
The actual code is as follows (lastest
werkzeug==0.14.1 at the time of writing):
def get_remote_addr(self, forwarded_for): if len(forwarded_for) >= self.num_proxies: return forwarded_for[-self.num_proxies]
Webfaction’s documentation about Accessing
…the IP address is available as the first IP address in the comma separated list in the
They don’t say what they do when a client request already contains
X-Forwarded-For header, but following common sense I would assume they replace it. Thus for Webfaction
num_proxies should be set to
Nginx is more explicit about it’s
the “X-Forwarded-For” client request header field with the
$remote_addrvariable appended to it, separated by a comma. If the “X-Forwarded-For” field is not present in the client request header, the
$proxy_add_x_forwarded_forvariable is equal to the
For Nginx in front of the app
num_proxies should be left at default
Rewriting the Ignas’s answer:
headers_list = request.headers.getlist("X-Forwarded-For") user_ip = headers_list if headers_list else request.remote_addr
Remember to read Eli’s post about spoofing considerations.
You can use
request.access_route to access list of ip :
if len(request.access_route) > 1: return request.access_route[-1] else: return request.access_route
You can just write this:
The problem is there’s probably some kind of proxy in front of Flask. In this case the “real” IP address can often be found in