【问题标题】:Secure Flask-SocketIO communication with basic authentication使用基本身份验证保护 Flask-SocketIO 通信
【发布时间】:2018-09-22 19:02:36
【问题描述】:

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

来自 Flask-SocketIO 在authentication 上的文档:

但是,在大多数情况下,在建立 SocketIO 连接之前执行传统的身份验证过程会更方便。然后,用户的身份可以记录在用户会话或 cookie 中,稍后当 SocketIO 连接建立时,SocketIO 事件处理程序将可以访问该信息。

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

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

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

【问题讨论】:

    标签: python authentication flask socket.io flask-socketio


    【解决方案1】:

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

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

    【讨论】:

    • 谢谢!我没有意识到connect 事件的特殊性。如果你有更多的时间,我的验证方案看起来合理吗? IE。验证用户名和密码的签名哈希。
    • 不需要将哈希存储在用户会话中,只是为了以后验证。只需写用户 ID,或者如果您不关心用户 ID,只需写 {"logged_in": True}。用户会话受到保护以防篡改,无需验证其内容。
    猜你喜欢
    • 2015-12-01
    • 2021-09-24
    • 2019-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多