Flask-Login + Flask-Sockets = 混乱

3

我已经安装了Flask-Login和Flask-Sockets。它们都可以正常工作,但是当尝试获取当前用户(使用g.user)时,会出现AttributeError:'_AppCtxGlobals' object has no attribute 'user'错误。

@sockets.route('/echo')
def echo_socket(ws):
    with app.app_context():
        user = current_user #This causes problems, just like basically anything else that uses something that is not provided in this function
        while True:
            message = ws.receive()
            ws.send("lol")

我对Flask还不太熟悉,非常需要帮助。


那么,你解决了之前的问题吗? - Martijn Pieters
是的,那个问题使用 with 解决了。 - High schooler
1个回答

7
问题在于您将套接字函数视为常规请求,但它们并不是。
在常规(即非套接字)情况下,客户端向服务器发送请求。每个请求都包含 Flask-Login 在登录时设置的 cookie。此 cookie 包含已登录的用户信息。Flask-Login 有一个 before_request 处理程序,它会读取此 cookie、加载用户信息,然后通过 current_user 公开该信息,因此在运行您的函数时,您就可以访问这些信息。
套接字连接与上述情况完全不同。对于套接字连接,客户端打开到路由的套接字,从而与服务器建立永久连接。这里不存在请求的概念,只是两台机器使用自己的协议发送和接收数据。由于没有 HTTP 请求,因此也没有 cookie、before_request 处理程序、应用程序和请求上下文以及 Flask-Login 的 current_user。套接字路由实际上在 Flask 应用程序之外运行。
如果您需要了解用户信息,则需要通过套接字接口发送凭据,并在套接字路由中自己验证这些凭据,因为由于缺少请求、cookie 等,Flask-Login 无法在套接字环境中工作。套接字路由与常规路由之间的一个重要区别是,套接字连接是永久的,因此只需要在建立连接时对用户进行身份验证。
希望这可以帮到您。很抱歉我没有快速简单的解决方案。

感谢您的回复,Miguel!您是否知道我还能用什么其他方式在Flask(和Flask-login)中添加实时功能? Flask-sockets似乎存在一些问题。 - High schooler
我也是你的Mega-tutorial的粉丝!它教会了我很多东西。 - High schooler
3
谢谢 :) Flask-Sockets是其他软件的轻量级包装器。我认为它或者gevent本身并没有问题,只是它们不适合你在Flask中习惯的服务器端模型。正如我在回答中所说,客户端需要发送凭据,这可以是完整的登录信息或更好的、在常规路由成功登录后生成的令牌。顺便说一句,这是个很棒的问题,我已经将这个主题添加到我的即将发布的博客文章列表中了。 - Miguel Grinberg
1
此外,Heroku在此主题上有一些信息可能会有所帮助:https://devcenter.heroku.com/articles/websocket-security#authentication-authorization - Miguel Grinberg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接