Flask、Flask-Login 和 Socket.io:即使不发送请求也保持会话活动
Flask, Flask-Login and Socket.io: Keep a session active even when not sending requests
我正在创建一个应用程序来可视化网页中来自远程科学仪器的一些数据。我正在使用 Flask 来开发它。我还使用 Flask-Login 来防止陌生人进入,并使用 Socket.io 在(客户端)浏览器和服务器之间进行交互,即将仪器(在 Python 中)的数据和状态发送给用户(Javascript 在浏览器上)。
我想使用 Flask-Login 让会话保持活动状态,比方说,10 分钟。我在博客中找到了这段代码(我也在我的应用程序中使用它),每次用户发送请求时它都会刷新会话(Flask 装饰器的一个很酷的使用 before_request
):
@app.before_request # Jordan Bonser snippet
def before_request():
session.permanent = True
app.permanent_session_lifetime = datetime.timedelta(minutes=10)
session.modified = True
g.user = current_user
当有人通过发送请求使用该应用程序时,这非常有效。我知道这意味着字面上浏览页面(粗略地说,在使用应用程序时执行 app.route
)。
问题是,在我的应用程序中,用户实际上只使用一个页面,同时观察数据是如何进入的,以及一些坐标和绘图是如何实时变化的,这是通过 SocketIO 实现的。这意味着如果我在超过 10 分钟的时间内积极使用该应用程序 - 尽管没有浏览页面 - 我的会话无论如何都会过期。
在这些情况下有什么方法可以使会话保持活动状态吗?我在想,每当用户在浏览器上有效接收到一些数据时,SocketIO 可以通过在服务器上执行一些 Flask 命令来帮助解决这个问题,但我真的不知道如何实现这一点。提前致谢。
有趣的问题。
不幸的是,Socket.IO 事件中的会话访问不是双向的。您可以获得会话的内容,但不能进行修改,因为整个 Socket.IO 会话发生在单个 WebSocket 请求中,因此无法发送带有会话更新的 HTTP 响应。
如果您愿意使用服务器端会话(您可以使用 Flask-Session 或 Flask-KVSession 扩展来实现),则规则会发生变化。如果会话存储在服务器控制的数据库中,那么您可以从 Socket.IO 进行更改,例如更新生命周期。
如果您决定继续使用来自 Flask 的基于 cookie 的默认会话,那么它会变得复杂。我认为您将需要停止使用会话永久生命周期设置,而是将 last_access
时间写入您的用户数据库(我假设您有一个用户数据库?)。您可以在 Socket.IO 事件以及 before_request
处理程序中更新此时间戳。在before_request
中你会检查最后一次访问时间戳,如果发现早于10分钟,那么你可以使会话无效。
我正在创建一个应用程序来可视化网页中来自远程科学仪器的一些数据。我正在使用 Flask 来开发它。我还使用 Flask-Login 来防止陌生人进入,并使用 Socket.io 在(客户端)浏览器和服务器之间进行交互,即将仪器(在 Python 中)的数据和状态发送给用户(Javascript 在浏览器上)。
我想使用 Flask-Login 让会话保持活动状态,比方说,10 分钟。我在博客中找到了这段代码(我也在我的应用程序中使用它),每次用户发送请求时它都会刷新会话(Flask 装饰器的一个很酷的使用 before_request
):
@app.before_request # Jordan Bonser snippet
def before_request():
session.permanent = True
app.permanent_session_lifetime = datetime.timedelta(minutes=10)
session.modified = True
g.user = current_user
当有人通过发送请求使用该应用程序时,这非常有效。我知道这意味着字面上浏览页面(粗略地说,在使用应用程序时执行 app.route
)。
问题是,在我的应用程序中,用户实际上只使用一个页面,同时观察数据是如何进入的,以及一些坐标和绘图是如何实时变化的,这是通过 SocketIO 实现的。这意味着如果我在超过 10 分钟的时间内积极使用该应用程序 - 尽管没有浏览页面 - 我的会话无论如何都会过期。
在这些情况下有什么方法可以使会话保持活动状态吗?我在想,每当用户在浏览器上有效接收到一些数据时,SocketIO 可以通过在服务器上执行一些 Flask 命令来帮助解决这个问题,但我真的不知道如何实现这一点。提前致谢。
有趣的问题。
不幸的是,Socket.IO 事件中的会话访问不是双向的。您可以获得会话的内容,但不能进行修改,因为整个 Socket.IO 会话发生在单个 WebSocket 请求中,因此无法发送带有会话更新的 HTTP 响应。
如果您愿意使用服务器端会话(您可以使用 Flask-Session 或 Flask-KVSession 扩展来实现),则规则会发生变化。如果会话存储在服务器控制的数据库中,那么您可以从 Socket.IO 进行更改,例如更新生命周期。
如果您决定继续使用来自 Flask 的基于 cookie 的默认会话,那么它会变得复杂。我认为您将需要停止使用会话永久生命周期设置,而是将 last_access
时间写入您的用户数据库(我假设您有一个用户数据库?)。您可以在 Socket.IO 事件以及 before_request
处理程序中更新此时间戳。在before_request
中你会检查最后一次访问时间戳,如果发现早于10分钟,那么你可以使会话无效。