在龙卷风下v4 + WebSocket连接被403拒绝

ayc*_*dee 12 nginx tornado websocket

我有一个较旧的龙卷风服务器,可以处理vanilla WebSocket连接.我通过Nginx将这些连接从wss://info.mydomain.com代理到wss://mydomain.com:8080,以便绕过阻止非标准端口的客户代理.

在最近升级到Tornado 4.0后,所有连接都被拒绝了403.导致此问题的原因是什么?如何解决?

ayc*_*dee 20

Tornado 4.0在默认情况下引入了一个相同的原点检查.这将检查浏览器设置的原始标头是否与主机标头相同

代码如下所示:

 def check_origin(self, origin):
    """Override to enable support for allowing alternate origins.

    The ``origin`` argument is the value of the ``Origin`` HTTP header,
    the url responsible for initiating this request.

    .. versionadded:: 4.0
    """
    parsed_origin = urlparse(origin)
    origin = parsed_origin.netloc
    origin = origin.lower()

    host = self.request.headers.get("Host")

    # Check to see that origin matches host directly, including ports
    return origin == host
Run Code Online (Sandbox Code Playgroud)

为了使代理的websocket连接仍然有效,您需要覆盖WebSocketHandler上的check origin并将您关注的域列入白名单.像这样的东西.

import re
from tornado import websocket

class YouConnection(websocket.WebSocketHandler):

    def check_origin(self, origin):
        return bool(re.match(r'^.*?\.mydomain\.com', origin))
Run Code Online (Sandbox Code Playgroud)

这将让来自的连接info.mydomain.com像以前一样通过.


tov*_*eod 5

我想提出和替代解决方案,而不是搞乱龙卷风应用程序代码,我通过告诉nginx修复主机头解决了这个问题:

location /ws {
proxy_set_header Host $host;
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
Run Code Online (Sandbox Code Playgroud)