Nginx / SSL 部署Flask websocket项目(gunicorn + gevent)http 400错误请求的问题

经过长时间的不成功的研究-我发现了很多主题相似的帖子,但没有一个能够解决我的问题-我也试图寻求帮助。

我正在码头工人内部使用gunicorn(和一个工人-w 1)和flask socket.io运行flask socket.io应用程序:
启动方式:
"gunicorn", "-k", "geventwebsocket.gunicorn.workers.GeventWebSocketWorker", "-w", "1", "app:app", "-b", "0.0.0.0:5000"

相应的python代码(async_mode为“ gevent”:
socketio = SocketIO(app, async_mode=async_mode)
socketio.run(app, host="0.0.0.0", port=5000, debug=True)

我正在前面运行一个nginx代理,只要我仅使用http,它就可以很好地工作。但是,当我切换到https时,出现很多HTTP 400错误,并且websockets停止工作。

我做了很多研究,发现了nginx选项,以及暗示只可以由一个工人来操作gunicorn。在我找到Miguel的这个简短选择之前,没有一个有效。
socketio = SocketIO(app, async_mode=async_mode,engineio_logger=True)

我确实添加了这个信息,并且在gunicorn日志上终于收到一条消息。
htts://mydomain is not within the accepted origins
经过几个小时的搜索,这使我进入了讨论

因此,我最终将cors选项添加到了我的socketio构造函数中:
socketio = SocketIO(app, async_mode=async_mode,cors_allowed_origins="*")

瞧,一切都很好!
不知道这是否与大多数在可能未检测到主机名或其他名称的容器中运行有关。但是,当我仍在研究时,我开始输入此“问题”,并认为这对于遇到类似问题的其他人可能是一个有趣的发现(因为我遇到了许多类似的要求)。

 

以下是更为有效安全的做法

 

我找到了解决此问题的更标准的方法(无需在您的代码中使用硬编码的域,也无需使用冒险的'*')。
您可以使用werkzeug的ProxyFix,它可以解决许多在代理后面运行应用程序的问题。

例如,我 在应用程序中使用url_forwith _external=True。没有ProxyFix我,则使用带有http协议的网址而不是所需的网址https
ProxyFix只要将代理服务器配置为传递X-Forwarded-*标头,就可以解决该问题以及您的原始问题。

用法示例:

from flask import Flask
from flask_socketio import SocketIO
from werkzeug.middleware.proxy_fix import ProxyFix

app = Flask(__name__)
app.secret_key = 'TODO: replace with a randomly generate secret key' # TODO: you can find how here: https://stackoverflow.com/questions/34902378/where-do-i-get-a-secret-key-for-flask
socketio = SocketIO(app)
app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1, x_proto=1)
socketio.run(app)

我的Nginx配置:

server {
    listen 443 ssl http2;
    server_name my.domain.com;

    <ssl stuff>    

    location / {
        include proxy_params;
        
        proxy_pass http://127.0.0.1:8000;
    }

    location /socket.io {
        include proxy_params;
        
        proxy_http_version 1.1;
        
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        
        proxy_pass http://127.0.0.1:8000/socket.io;
    }
}

server {
    if ($host = my.domain.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    listen 80;
    server_name my.domain.com;
}

/etc/nginx/proxy_params

proxy_set_header Host $http_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;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值