Autobahn | Сервер Python Twisted, который проверяет ключ API и отключает клиентов

Я хочу добавить простую проверку ключа API на сервер Autobahn Python WebSocket. Сервер должен проверить ключ в HTTP-заголовке клиента и отключить клиентов, у которых нет правильного ключа.

Я нашел решение этой проблемы, но не уверен, что это лучшее решение (см. Ниже). Если у кого-то есть предложения, я был бы признателен.


person eric    schedule 10.03.2016    source источник


Ответы (2)


Из документации по API для onConnect метод:

Используйте autobahn.websocket.types.ConnectionDeny, если не хотите принимать запрос на соединение с WebSocket.

Вы можете увидеть это в строке 117 одного из примеров здесь.

Я проверил это, и он не полностью закрывает соединение. Однако вы завершаете соединение с неаутентифицированным клиентом, поэтому вам не следует выполнять закрывающее рукопожатие.

Обратный вызов onClose принимает аргумент wasClean, который позволяет различать чистое и нечистое закрытие соединения.

person Henry Heath    schedule 25.04.2016

Мое решение - проверить заголовок 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 на стороне сервера причиной того, что сервер закрыл соединение, а клиент не отправил ответ, причину? Есть лучший способ сделать это?

Обновление: я принял ответ Генри Хита, потому что это, кажется, официально поддерживаемое решение, хотя оно не закрывает соединение чисто. Используя 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.

person eric    schedule 10.03.2016