我有一个 Flask 应用程序在 NGINX 反向代理后面运行。在我的一个函数中,我需要构建一个指向不同服务的 URL,并且我希望将 HTTP 方案与 NGINX 条目方案相匹配。因此,如果 NGINX 反向代理 https 请求,我想生成一个像
https://my_other_service
这样的 url。但如果 NGINX 反向代理 http
我希望它是 http://my_other_service
。
当我将
flask.url_for
函数用于同一应用程序中的端点时,它能够自动确定代理方案,因此我认为这一定是可能的,但在我的情况下,我生成的 url 不是当前 Flask 中的端点应用程序。
如何确定 Flask 应用程序内的代理方案?
正如在这个问题上所描述的,你可以直接告诉
url_for
在生成URL时使用特定的方案:
url_for('secure_thingy',
_external=True,
_scheme='https',
viewarg1=1, ...)
当然,问题是你不一定知道 URL 是否应该是 https。如果它在生产环境中运行在 Nginx 后面,则它必须是 https。如果它运行在本地主机上进行本地开发,也许 https 不起作用。
一种解决方案是为您的应用程序设置要使用的方案的配置设置。在您的开发环境中,它将设置为 http。在您的生产环境中,您将使用 https。这就是我要做的。
另一种方法是告诉 Nginx 传递一个特殊的标头,然后您可以使用它来更改方案。
Nginx 站点上有 有关添加标头的说明,所以这里是一个示例:
location /some/path/ {
proxy_set_header X-Force-Https "yes";
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://localhost:8000;
}
然后在 Flask 代码中,仅将
_scheme='https'
传递给 url_for
(如果 request.headers.get('X-Force-Https', None) == 'yes'
)。
这是一个更加自动化的解决方案,但需要您修改生产 Web 服务器环境。
强制将请求端口更改为 80 并将请求重定向到 nginx 代理:
@app.route('/some/<path>/', methods=['GET'])
def gotty(path):
request.host = request.host.split(':')[0]+':80'
return redirect(request.url, code=302)