如何在 Flask 应用程序中获取代理方案?

How do I get the proxy scheme inside a Flask app?

我有一个 运行 在 NGINX 反向代理后面的 Flask 应用程序。在我的一个函数中,我需要为不同的服务构造一个 URL 并且我希望将 HTTP 方案与 NGINX 入口方案相匹配。因此,如果 NGINX 正在反向代理 https 请求,我想生成一个 url,如 https://my_other_service。但是如果 NGINX 反向代理 http 我希望它是 http://my_other_service.

当我将 flask.url_for 函数用于同一应用程序中的端点时,它能够自动确定代理方案,所以我认为这一定是可能的,但在我的情况下 url 我' m 生成不是当前 Flask 应用程序中的端点。

如何确定 Flask 应用程序中的代理方案?

作为described on this question,可以直接告诉url_for在生成URL时使用特定方案:

url_for('secure_thingy',
        _external=True,
        _scheme='https',
        viewarg1=1, ...)

当然,问题在于您不一定知道 URL 是否应该是 https。如果它在生产中落后于 Nginx 运行,它必须是 https。如果是 运行 在 localhost 上进行本地开发,可能 https 就不行了。

一个解决方案是为您的应用程序配置一个关于使用什么方案的配置设置。在您的开发环境中,它将设置为 http。在您的生产环境中,您将使用 https。这就是我会做的。

另一种方法是让 Nginx 传递一个特殊的 header,然后您可以使用它来更改方案。

instructions on adding headers on the Nginx site,举个例子:

location /some/path/ {
    proxy_set_header X-Force-Https "yes";
    proxy_set_header X-Real-IP $remote_addr;
    proxy_pass http://localhost:8000;
}

然后在您的 Flask 代码中,如果 request.headers.get('X-Force-Https', None) == 'yes'.

则仅将 _scheme='https' 传递给 url_for

这是一个更自动化的解决方案,但需要您修改生产 Web 服务器环境。