Autobahn | Python Twisted服务器,用于检查API密钥并断开客户端连接

时间:2016-03-10 07:45:03

标签: python websocket twisted autobahn

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

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

2 个答案:

答案 0 :(得分:0)

我的解决方案是在客户端连接到服务器后检查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

服务器端的关闭消息是否为服务器关闭连接而客户端没有发回原因的原因是什么?有更好的方法吗?

<强>更新 我接受了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中,可以使用request.headers访问HTTP标头,而在onOpen中,可以使用self.http_headers访问它们。

答案 1 :(得分:0)

来自onConnect方法的API Docs

  

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

您可以在其中一个示例here的第117行看到此内容。

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

onClose回调采用一个wasClean参数,允许您区分干净和不干净的连接闭包。