Autobahn|Python 检查 API 密钥并断开客户端连接的扭曲服务器
Autobahn|Python Twisted server that checks API key and disconnects clients
我想向 Autobahn Python WebSocket 服务器添加一个简单的 API 密钥检查。服务器应检查客户端 HTTP header 中的密钥,并断开没有正确密钥的客户端。
我已经想出了一个解决方案,但我不确定这是最好的解决方案(见下文)。如果有人有建议,我将不胜感激。
我的解决方案是在客户端连接到服务器后检查 HTTP header,如果客户端没有有效的 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
服务器端close消息是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 header 可通过 request.headers 访问,而在 onOpen 中,它们可通过 self.http_headers 访问。
来自 API Docs 的 onConnect 方法:
Throw autobahn.websocket.types.ConnectionDeny when you don’t want to accept the WebSocket connection request.
您可以在示例之一的第 117 行看到此操作 here。
我已经对此进行了测试,它不会完全关闭连接。但是,您正在终止与未经身份验证的客户端的连接,因此您不应该进行关闭握手。
onClose 回调采用 wasClean 参数,它允许您区分干净和不干净的连接关闭。
我想向 Autobahn Python WebSocket 服务器添加一个简单的 API 密钥检查。服务器应检查客户端 HTTP header 中的密钥,并断开没有正确密钥的客户端。
我已经想出了一个解决方案,但我不确定这是最好的解决方案(见下文)。如果有人有建议,我将不胜感激。
我的解决方案是在客户端连接到服务器后检查 HTTP header,如果客户端没有有效的 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
服务器端close消息是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 header 可通过 request.headers 访问,而在 onOpen 中,它们可通过 self.http_headers 访问。
来自 API Docs 的 onConnect 方法:
Throw autobahn.websocket.types.ConnectionDeny when you don’t want to accept the WebSocket connection request.
您可以在示例之一的第 117 行看到此操作 here。
我已经对此进行了测试,它不会完全关闭连接。但是,您正在终止与未经身份验证的客户端的连接,因此您不应该进行关闭握手。
onClose 回调采用 wasClean 参数,它允许您区分干净和不干净的连接关闭。