使用基本身份验证保护 Flask-SocketIO 通信

Secure Flask-SocketIO communication with basic authentication

我有一个使用基本身份验证进行身份验证的 Flask-SocketIO 应用程序。我正在努力确保我的所有 socketio 通信也受到保护,至少与基本身份验证的程度相同。

来自 Flask-SocketIO 关于 authentication 的文档:

However, in most cases it is more convenient to perform the traditional authentication process before the SocketIO connection is established. The user’s identity can then be recorded in the user session or in a cookie, and later when the SocketIO connection is established that information will be accessible to SocketIO event handlers.

因此,我试图弄清楚如何在用户会话中安全地存储一些东西。假设我执行以下操作,首先登录,我签署了哈希用户名和密码:

from flask import session
from itsdangerous import Signer

signer = Signer('super secret key')
def login(username: str, password: str):
    if (username, password) in credentials:
        hashed = hash(username + password)
        session['user'] = s.sign(hashed)

然后我可以为我的 socketio 侦听器制作一个装饰器,它只检查会话中的签名值是否有效:

def authenticated_only(f):
    @functools.wraps(f)
    def wrapped(*args, **kwargs):
        try:
            signer.unsign(session['user'])
            return f(*args, **kwargs)
        except BadSignature:
            disconnect()
    return wrapped

@socketio.on('my event')
@authenticated_only
def handle_my_custom_event(data):
    pass

这是一个合理的方法吗?有没有我遗漏的陷阱?这是没有意义的,因为我使用的是基本身份验证吗?

Socket.IO 使用与每个客户端的永久连接,因此实际上只需要验证 connect 事件。如果用户无效,您 return False 来自此事件并且连接将不被接受。在任何其他情况下,连接都经过身份验证,无需在用户每次发出事件时再次验证用户。

由于只需要对用户进行一次验证,所以我倾向于不为此编写装饰器,直接在连接事件处理程序中添加验证逻辑。