<h2>Werkzeug中间件</h2>
<p>Flask的文档非常具体<a href="http://flask.pocoo.org/docs/1.0/deploying/wsgi-standalone/#proxy-setups" rel="nofollow noreferrer">about recommended reverse proxy server setup</a>:</p>
<blockquote>
<p>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 <code>REMOTE_ADDR</code> and <code>HTTP_HOST</code>... Werkzeug ships a fixer that will solve some common setups, but you might want to write your own WSGI middleware for specific setups.</p>
</blockquote>
<p>关于安全考虑:</p>
<blockquote>
<p>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.</p>
</blockquote>
<p>建议的代码(安装中间件)将使<code>request.remote_addr</code>返回客户端IP地址为:</p>
<pre><code>from werkzeug.contrib.fixers import ProxyFix
app.wsgi_app = ProxyFix(app.wsgi_app, num_proxies=1)
</code></pre>
<p>注意<code>num_proxies</code>,默认为<code>1</code>。这是应用程序前面的代理服务器数。</p>
<p>实际代码如下(编写时的最后一个<code>werkzeug==0.14.1</code>):</p>
<pre><code>def get_remote_addr(self, forwarded_for):
if len(forwarded_for) >= self.num_proxies:
return forwarded_for[-self.num_proxies]
</code></pre>
<h2>网络势力</h2>
<p>Webfaction关于<a href="https://docs.webfaction.com/software/django/troubleshooting.html#accessing-remote-addr" rel="nofollow noreferrer">Accessing ^{<cd5>}</a>的文档说:</p>
<blockquote>
<p>...the IP address is available as the first IP address in the comma separated list in the <code>HTTP_X_FORWARDED_FOR</code> header.</p>
</blockquote>
<p>他们不会说当客户机请求已经包含<code>X-Forwarded-For</code>头时他们会做什么,但是根据常识,我假设他们会替换它。因此,对于Webfaction,应该将<code>num_proxies</code>设置为<code>0</code>。</p>
<h2>Nginx公司</h2>
<p>Nginx更明确地说是<a href="http://nginx.org/en/docs/http/ngx_http_proxy_module.html#var_proxy_add_x_forwarded_for" rel="nofollow noreferrer">^{<cd9>}</a>:</p>
<blockquote>
<p>the “X-Forwarded-For” client request header field with the <code>$remote_addr</code> variable appended to it, separated by a comma. If the “X-Forwarded-For” field is not present in the client request header, the <code>$proxy_add_x_forwarded_for</code> variable is equal to the <code>$remote_addr</code> variable.</p>
</blockquote>
<p>对于应用程序前面的Nginx,<code>num_proxies</code>应该保留默认值<code>1</code>。</p>