我如何确保Tornado只打开具有已验证用户的websocket?

我如何确保Tornado只打开具有已验证用户的websocket?,websocket,tornado,Websocket,Tornado,Tornado文档没有对与WebSocketHandler一起使用的Tornado.web.authenticated装饰器的任何使用进行评论。我只想将websocket连接授予经过身份验证的用户 通过测试,在连接设置握手时,WebSocketHandler上似乎正在调用initialize(),以获取请求。因此,我可以想象覆盖initialize()并通过检查cookie中是否存在有效的会话令牌来检查用户是否以标准方式进行了身份验证 但在我着手进行这项工作之前,我想把它公布给社区,看看这是否是

Tornado文档没有对与
WebSocketHandler
一起使用的
Tornado.web.authenticated
装饰器的任何使用进行评论。我只想将websocket连接授予经过身份验证的用户

通过测试,在连接设置握手时,
WebSocketHandler
上似乎正在调用
initialize()
,以获取请求。因此,我可以想象覆盖
initialize()
并通过检查cookie中是否存在有效的会话令牌来检查用户是否以标准方式进行了身份验证

但在我着手进行这项工作之前,我想把它公布给社区,看看这是否是正确的方法

  • 有没有一种简单而快速的方法可以让
    WebSocketHandler
    只继续握手来建立连接,就像
    tornado.web.authenticated
    装饰程序那样

  • 我很惊讶这不是内置的。我是否遗漏了一些关于WebSocket以及如何保护它们的信息


  • 编辑:
    请通过覆盖
    \u execute()
    方法而不是
    initialize()
    方法来查看下面可能的答案。

    很抱歉在发布后一小时内回答了我自己的问题。。。但我想把下面的想法说出来。非常好奇是否有更好的方法,因为当我不得不使用覆盖“下划线”方法并在流上编写低级消息时,它总是让我感到紧张。。。但似乎有效

    下面的处理程序在继续使用“_execute()”方法(检查GET请求并继续使用握手逻辑)之前检查身份验证


    需要覆盖
    \u execute()
    而不是
    initialize()
    的原因与Tornado如何扩展
    Tornado.web.RequestHandler
    的结构有关。似乎没有一种优雅的方式可以用适当的响应退出IOloop

    我不知道为什么之前的答案被否决了,但我发现这是一个更合适的答案,而不是覆盖open()。当open被调用时,已经发生了很多事情,比如协议升级和websocket连接被打开。那么再次关闭此项将增加额外的开销

    重写_execute是正确的方法。 对于tornado 4.0+,您应该像这样重写get方法

    class WbSocketHandler(tornado.websocket.WebSocketHandler):
      @tornado.web.asynchronous
      def get(self, *args, **kwargs):
        if (not self.current_user):
          self.set_status(401)
          self.finish("Unauthorized")
          return
        super(WbSocketHandler, self).get(*args, **kwargs)
    

    如果用户未经授权,最好的方法是覆盖
    open()
    并使用错误代码调用
    self.close()
    。如果确实要返回HTTP错误而不是websocket错误,则可以替代
    prepare()
    。重写
    get()
    \u execute()
    是脆弱的,不受鼓励的。

    重写open(),如果用户未登录,则调用self.close()。你可以通过饼干来决定。无需重写_execute等。
    class WbSocketHandler(tornado.websocket.WebSocketHandler):
      @tornado.web.asynchronous
      def get(self, *args, **kwargs):
        if (not self.current_user):
          self.set_status(401)
          self.finish("Unauthorized")
          return
        super(WbSocketHandler, self).get(*args, **kwargs)