Flask request.remote_addr在webfaction上是错误的,并且没有显示真实的用户IP

时间:2012-10-07 17:09:15

标签: python flask webfaction

我刚刚在Webfaction上部署了一个Flask应用,我注意到request.remote_addr总是127.0.0.1。这当然没什么用。

如何在Webfaction上的Flask中获取用户的真实IP地址?

谢谢!

5 个答案:

答案 0 :(得分:32)

如果Flask面前有代理,那么像这样的东西将在Flask中得到真正的IP:

if request.headers.getlist("X-Forwarded-For"):
   ip = request.headers.getlist("X-Forwarded-For")[0]
else:
   ip = request.remote_addr

更新: Eli在评论中提到的非常好的观点。如果您只是使用它,可能会出现一些安全问题。阅读Eli's post以获取更多详细信息。

答案 1 :(得分:4)

Werkzeug中间件

Flask的文档非常具体about recommended reverse proxy server setup

  

如果使用HTTP [反向]代理后面的这些[WSGI]服务器之一部署应用程序,则您将需要重写一些标头才能使该应用程序正常运行。 WSGI环境中的两个有问题的值通常是REMOTE_ADDRHTTP_HOST ... Werkzeug附带了一个可解决一些常见设置的修复程序,但是您可能想为特定设置编写自己的WSGI中间件。 / p>

还有安全方面的考虑:

  

请记住,在非代理设置中使用这样的中间件是一个安全问题,因为它会盲目地信任可能由恶意客户端伪造的传入标头。

将使request.remote_addr返回客户端IP地址的建议代码(安装中间件)为:

from werkzeug.contrib.fixers import ProxyFix
app.wsgi_app = ProxyFix(app.wsgi_app, num_proxies=1)

请注意,num_proxies默认为1。这是应用程序前面的代理服务器的数量

实际代码如下(在撰写本文时,最新的werkzeug==0.14.1):

def get_remote_addr(self, forwarded_for):
    if len(forwarded_for) >= self.num_proxies:
        return forwarded_for[-self.num_proxies]

Webfaction

Webfaction关于Accessing REMOTE_ADDR的文档说:

  

...该IP地址可用作HTTP_X_FORWARDED_FOR标头中逗号分隔列表中的第一个IP地址。

当客户请求中已经包含X-Forwarded-For标头时,他们不会说什么,但是按照常识,我认为他们会替换标头。因此,对于Webfaction,num_proxies应该设置为0

Nginx

Nginx的$proxy_add_x_forwarded_for更明确:

  

附加了$remote_addr变量的“ X-Forwarded-For”客户端请求标头字段,以逗号分隔。如果客户端请求标头中不存在“ X-Forwarded-For”字段,则$proxy_add_x_forwarded_for变量等于$remote_addr变量。

对于应用前的Nginx,num_proxies应该保留为默认值1

答案 2 :(得分:3)

问题是在Flask面前可能有某种代理。在这种情况下,“真实”IP地址通常可以在request.headers['X-Forwarded-For']中找到。

答案 3 :(得分:3)

重写Ignas的回答:

headers_list = request.headers.getlist("X-Forwarded-For")
user_ip = headers_list[0] if headers_list else request.remote_addr

请务必阅读有关欺骗注意事项的Eli's post

答案 4 :(得分:2)

您可以使用request.access_route访问ip列表:

if len(request.access_route) > 1:
    return request.access_route[-1]
else:
    return request.access_route[0]

更新

你可以这样写:

    return request.access_route[-1]