0

Tornado 文档没有评论tornado.web.authenticated装饰器与WebSocketHandler. 我只想向经过身份验证的用户授予 websocket 连接。

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

但在我动手之前 - 我想把它发布给社区,看看这是否是正确的方法。

  1. 是否有一种简单快捷的方法可以WebSocketHandler只继续握手以建立连接 - 以类似于tornado.web.authenticated装饰器的方式?

  2. 我很惊讶这不是内置的。我是否缺少有关 websockets 以及如何保护它们的信息?


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

4

3 回答 3

2

如果用户未被授权,最好的方法是覆盖open()并使用错误代码调用。self.close()如果你真的想返回 HTTP 错误而不是 websocket 错误,你可以重写prepare()。覆盖get()or_execute()是脆弱和不鼓励的。

于 2016-01-29T01:28:48.033 回答
0

我不知道为什么以前的答案被否决,但我发现它是一个更合适的答案,而不是覆盖 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)
于 2015-09-20T15:50:34.447 回答
-1

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

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

import logging

import tornado.escape
import tornado.websocket


class AuthenticatedWebsocketHandler(tornado.websocket.WebSocketHandler):
    '''Only allows a request to open a websocket for a valid current user.
       This class assumes that the get_current_user() method is defined
       to check for a valid session id. (see Tornado docs).
    '''
    def _execute(self, *args, **kwds):
        if not self.current_user:
            logging.warn('Unauthorized attempt by {} to open websocket.'
                    .format(self.request.remote_ip))

            self.stream.write(tornado.escape.utf8(
                'HTTP/1.1 401 Unauthorized\r\n\r\n'
                'Not authenticated.'))

            self.stream.close()
            return

        super(AuthenticatedWebsocketHandler, self)._execute(*args, **kwds)

_execute()需要覆盖而不是与Tornadoinitialize()扩展的结构tornado.web.RequestHandler有关tornado.websocket.WebSocketHandler。否则似乎没有一种优雅的方式来退出 IOloop 并提供适当的响应。

于 2013-04-28T20:28:16.950 回答