【问题标题】:Autobahn|Python Twisted server that checks API key and disconnects clientsAutobahn|Python Twisted 服务器,用于检查 API 密钥并断开客户端连接
【发布时间】:2016-03-10 07:45:03
【问题描述】:

我想向 Autobahn Python WebSocket 服务器添加一个简单的 API 密钥检查。服务器应检查客户端 HTTP 标头中的密钥,并断开没有正确密钥的客户端。

我已经找到了解决方案,但我不确定它是否是最好的解决方案(见下文)。如果有人有建议,我将不胜感激。

【问题讨论】:

    标签: python websocket twisted autobahn


    【解决方案1】:

    来自API Docs 的 onConnect 方法:

    当你不想接受 WebSocket 连接请求时,抛出 autobahn.websocket.types.ConnectionDeny。

    您可以在 here 示例之一的第 117 行看到此操作。

    我已经对此进行了测试,它确实干净地关闭了连接。但是,您正在终止与未经身份验证的客户端的连接,因此您不希望通过关闭握手。

    onClose 回调采用 wasClean 参数,可让您区分干净和不干净的连接闭包。

    【讨论】:

      【解决方案2】:

      我的解决方案是在客户端连接到服务器后检查 HTTP 标头,如果客户端没有有效的 API 密钥,则关闭连接。

      MY_API_KEY = u'12345'
      
      class MyServerProtocol(WebSocketServerProtocol):
      
          def onConnect(self, request):
              print("Client connecting: {}".format(request.peer))
      
          def onOpen(self):
              # Check API Key
              if 'my-api-key' not in self.http_headers or\
                  self.http_headers['my-api-key'] != MY_API_KEY:
                  # Disconnect the client
                  print('Missing/Invalid Key')
                  self.sendClose( 4000, u'Missing/Invalid Key')
      
              # Register client
              self.factory.register(self)
      

      我发现如果我关闭 onConnect 内部的连接,我会收到一条错误消息,提示我无法关闭尚未连接的连接。上述解决方案在客户端完全关闭,但在服务器端表现异常。日志输出是

      dropping connection: None
      Connection to/from tcp4:127.0.0.1:51967 was aborted locally
      _connectionLost: [Failure instance: Traceback (failure with no frames): <class 'twisted.internet.error.ConnectionAborted'>: Connection was aborted locally, using.
          ]
      WebSocket connection closed: None
      

      服务器端关闭消息为None的原因是服务器关闭了连接而客户端没有发回原因吗?有没有更好的方法来做到这一点?

      更新: 我接受了 Henry Heath 的回答,因为它似乎是官方支持的解决方案,即使它没有完全关闭连接。使用autobahn.websocket.types.ConnectionDeny,解决方案就变成了

      from autobahn.websocket.types import ConnectionDeny
      MY_API_KEY = u'12345'
      
      class MyServerProtocol(WebSocketServerProtocol):
      
          def onConnect(self, request):
              print("Client connecting: {}".format(request.peer))
              # Check API Key
              if 'my-api-key' not in request.headers or\
                  request.headers['my-api-key'] != MY_API_KEY:
                  # Disconnect the client
                  print('Missing/Invalid Key')
                  raise ConnectionDeny( 4000, u'Missing/Invalid Key')
      
          def onOpen(self):
              # Register client
              self.factory.register(self)
      

      请注意,在 onConnect 中,HTTP 标头可以通过 request.headers 访问,而在 onOpen 中,它们可以通过 self.http_headers 访问。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-09-11
        • 2015-01-15
        • 2013-08-13
        • 2014-07-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多