简体   繁体   English

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

[英]Autobahn|Python Twisted server that checks API key and disconnects clients

I want to add a simple API key check to an Autobahn Python WebSocket server. 我想向Autobahn Python WebSocket服务器添加一个简单的API密钥检查。 The server should check the key in the HTTP header of a client and disconnect clients that don't have the correct key. 服务器应检查客户端HTTP标头中的密钥,并断开没有正确密钥的客户端。

I have figured out a solution to this, but I'm not sure it is the best solution (see below). 我已经找到了解决方案,但是我不确定这是最好的解决方案(见下文)。 If anyone has suggestions, I'd appreciate it. 如果有人提出建议,我将不胜感激。

From the API Docs for the onConnect method: API文档中的onConnect方法:

Throw autobahn.websocket.types.ConnectionDeny when you don't want to accept the WebSocket connection request. 当您不想接受WebSocket连接请求时,抛出autobahn.websocket.types.ConnectionDeny。

You can see this done on line 117 of one of the examples here . 你可以看到的例子之一的117线完成这件事在这里

I have tested this and it does not close the connection cleanly. 我已经对此进行了测试,它不能干净地关闭连接。 However you are terminating a connection with an unauthenticated client so you should not want to go through a closing handshake. 但是,您将终止与未经身份验证的客户端的连接,因此您不希望进行关闭握手。

The onClose callback takes a wasClean argument which allows you to differentiate between clean and unclean connection closures. onClose回调函数使用wasClean参数,该参数可让您区分干净连接和不干净连接的关闭。

My solution is to check the HTTP header after the client has connected to the server and to close the connection if the client does not have a valid API key. 我的解决方案是在客户端连接到服务器后检查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)

I found that if I close the connection inside onConnect, I get an error saying that I cannot close a connection that has not yet connected. 我发现如果关闭onConnect内的连接,则会收到一条错误消息,提示我无法关闭尚未连接的连接。 The above solution closes cleanly on the client side, but behaves oddly on the server side. 上面的解决方案在客户端完全关闭,但在服务器端却表现异常。 The log output is 日志输出为

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

Is the reason the close message is None on the server side that the server closed the connection and the client did not send back a reason? 服务器关闭消息为“无”的原因是服务器关闭了连接并且客户端没有发回邮件吗? Is there a better way to do this? 有一个更好的方法吗?

Update: I have accepted Henry Heath's answer because it seems to be the officially supported solution, even though it does not close the connection cleanly. 更新:我接受了亨利·希思的回答,因为它似乎是官方支持的解决方案,即使它不能干净地关闭连接。 Using autobahn.websocket.types.ConnectionDeny , the solution becomes 使用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)

Note that within onConnect, HTTP headers are accessible with request.headers whereas within onOpen, they are accessible with self.http_headers. 请注意,在onConnect中,HTTP标头可通过request.headers访问,而在onOpen中,它们可通过self.http_headers访问。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM