Nginx反向代理到Flask应用request.scheme获取不到https问题

技术 · 02-28
Nginx反向代理到Flask应用request.scheme获取不到https问题

代理设置

如果你在使用HTTP代理服务器部署你的应用程序,你需要重写一些头部信息,以便应用程序能够正常工作。在WSGI环境中,通常有两个有问题的值是REMOTE_ADDR和HTTP_HOST。你可以配置你的httpd来传递这些头部信息,或者你可以在中间件中修复它们。Werkzeug附带了一个修复器,可以解决一些常见的设置问题,但你可能需要为自己的特定设置编写自己的WSGI中间件。

下面是一个简单的nginx配置,该配置将代理到在localhost的8000端口上运行的应用程序,并设置适当的头部信息:

server {
    listen 80;

    server_name _;

    access_log  /var/log/nginx/access.log;
    error_log  /var/log/nginx/error.log;

    location / {
        proxy_pass         http://127.0.0.1:8000/;
        proxy_redirect     off;

        proxy_set_header   Host                 $host;
        proxy_set_header   X-Real-IP            $remote_addr;
        proxy_set_header   X-Forwarded-For      $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto    $scheme;
    }
}

如果你的httpd没有提供这些头部信息,最常见的设置是从X-Forwarded-Host设置主机,从X-Forwarded-For设置远程地址:

from werkzeug.middleware.proxy_fix import ProxyFix
app.wsgi_app = ProxyFix(app.wsgi_app, x_proto=1, x_host=1)

信任头部

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

如果你想要从另一个头部重写头部信息,你可能想要使用像这样的修复器:

class CustomProxyFix(object):

    def __init__(self, app):
        self.app = app

    def __call__(self, environ, start_response):
        host = environ.get('HTTP_X_FHOST', '')
        if host:
            environ['HTTP_HOST'] = host
        return self.app(environ, start_response)

app.wsgi_app = CustomProxyFix(app.wsgi_app)

参考
https://flask.palletsprojects.com/en/2.0.x/deploying/wsgi-standalone/

Nginx Flask
Theme Jasmine by Kent Liao