简体   繁体   English

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

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

I have a Flask application that is running behind an NGINX reverse proxy.我有一个 Flask 应用程序在 NGINX 反向代理后面运行。 In one of my functions I need to construct a URL to a different service and I wish to match the HTTP scheme to whatever the NGINX entry scheme is.在我的一个功能中,我需要将 URL 构建到不同的服务,并且我希望将 HTTP 方案与 NGINX 条目方案相匹配。 So if NGINX is reverse proxying an https request, I'd like to generate a url like https://my_other_service . So if NGINX is reverse proxying an https request, I'd like to generate a url like https://my_other_service . But if NGINX reverse proxies an http I'd like it to be http://my_other_service .但是,如果 NGINX 反向代理http我希望它是http://my_other_service

The flask.url_for function is able to automatically determine the proxy scheme when I use it for endpoints in the same app so I figure this must be possible, but in my case the url I'm generating is not an endpoint in the current Flask app. The flask.url_for function is able to automatically determine the proxy scheme when I use it for endpoints in the same app so I figure this must be possible, but in my case the url I'm generating is not an endpoint in the current Flask app .

How can I determine the proxy scheme inside a flask app?如何确定 flask 应用程序中的代理方案?

As described on this question , you can directly tell url_for to use a specific scheme when generating a URL:本问题所述,您可以在生成 URL 时直接告诉url_for使用特定方案:

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

The problem, of course, is that you don't necessarily know whether the URL should be https or not.当然,问题在于您不一定知道 URL 是否应该是 https。 If it's running behind Nginx in production, it must be https.如果它在生产中运行在 Nginx 后面,它必须是 https。 If it's running on localhost for local development, perhaps https wouldn't work.如果它在 localhost 上运行以进行本地开发,则 https 可能不起作用。

One solution would be to just have a configuration setting for your app on what scheme to use.一种解决方案是只为您的应用程序设置一个关于使用什么方案的配置设置。 In your development environment, it would be set to http.在您的开发环境中,它将设置为 http。 In your production environment, you'd use https.在您的生产环境中,您将使用 https。 That's what I would do.这就是我会做的。

An alternative is to tell Nginx to pass along a special header which you could then use to alter the scheme.另一种方法是告诉 Nginx 传递一个特殊的 header 然后您可以使用它来更改方案。

There are instructions on adding headers on the Nginx site , so here's an example: Nginx 网站上有关于添加标题的说明,所以这里有一个例子:

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

Then in your Flask code, only pass _scheme='https' to url_for if request.headers.get('X-Force-Https', None) == 'yes' .然后在您的 Flask 代码中,仅将_scheme='https'传递给url_for if request.headers.get('X-Force-Https', None) == 'yes'

That's a more automatic solution, but will require you to modify your production web server environment.这是一个更加自动化的解决方案,但需要您修改生产 web 服务器环境。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM