Flask - 像使用 cookie 一样将会话数据保存在数据库中

Posted

技术标签:

【中文标题】Flask - 像使用 cookie 一样将会话数据保存在数据库中【英文标题】:Flask - Save session data in database like using cookies 【发布时间】:2013-07-15 16:36:40 【问题描述】:

我正在使用 Flask 创建一个 Web 应用程序。

我想知道是否可以像这样保存用户会话数据

session['ishappy'] = true

在数据库中,就像在 Django 中使用 SessionMiddleware 一样,您可以在 cookie 和数据库之间进行选择。

如果它是我应该导入到我的 Flask 应用程序的内容。

【问题讨论】:

【参考方案1】:

我建议您通过继承烧瓶默认值来实现自己的 Session 和 SessionInterface。基本上,你需要定义自己的会话类和会话接口类。

class MyDatabaseSession(CallbackDict, SessionMixin):

    def __init__(self, initial=None, sid=None):
        CallbackDict.__init__(self, initial)
        self.sid = sid
        self.modified = False

上面的类现在将有一个将存储在cookie中的会话ID(sid)。与此会话 ID 相关的所有数据都将存储在您的 mysql 数据库中。为此,您需要实现以下类和方法:

class MyDatabaseSessionInterface(SessionInterface):

    def __init__(self, db):
        # this could be your mysql database or sqlalchemy db object
        self.db = db

    def open_session(self, app, request):
        # query your cookie for the session id
        sid = request.cookies.get(app.session_cookie_name)

        if sid:
            # Now you query the session data in your database
            # finally you will return a MyDatabaseSession object
     
    def save_session(self, app, session, response):
        # save the sesion data if exists in db
        # return a response cookie with details
        response.set_cookie(....) 

另外,您可以定义一个模型来存储会话数据:

class SessionData(db.Model):
    def __init__(self,sid,data):
        self.sid = sid
        self.data = data
        # and so on...

下面的sn-ps应该会给你一个思路:

https://github.com/fengsp/flask-snippets/blob/master/sessions/redis_session.py

https://github.com/fengsp/flask-snippets/blob/master/sessions/sqlite_session.py

https://github.com/fengsp/flask-snippets/blob/master/sessions/mongodb_session.py

【讨论】:

是否可以在没有 redis 的情况下使用它,例如在 MySQL 数据库上? 因为我使用 MySQL 和 SQLAlchemy,我想知道如何将会话连接到它们。 是的,这是可能的。您只需要确保在读取/写入 mysql 数据库的位置实现了 open_session() 和 save_session() 方法。 好的,那么我应该在例如 Sessions 中实现一个模型吗?模型 my 其中包含一个密钥,例如user_id、过期时间和blob?在保存会话时,用户登录时“在浏览器中”保存的所有数据都应该使用密钥进行编码并保存在 db 中,是吗? 我添加了一些示例代码/伪代码给你一个想法。他们需要注意的重要一点是会话 ID 本身需要在 cookie 中,而实际数据在数据库中。这样,请求对象可以只传递带有会话 ID 的签名 cookie。【参考方案2】:

你应该看看Flask-KVSession,它自称是

Flask 签名的替代品 基于 cookie 的会话管理。而不是将数据存储在 客户端,只有一个安全生成的 ID 存储在客户端,而 实际的会话数据驻留在服务器上。

这基本上描述了传统的服务器端会话。请注意,它支持多个数据库后端:

Flask-KVSession 使用simplekv 包在各种后端存储会话数据。

请参阅Example Use 了解导入内容和配置方法的示例。

【讨论】:

【参考方案3】:

一位同事最近发布了这篇文章,解释了如何工作和共享用户会话。希望对您有所帮助:

Django, Flask, and Redis: Sharing User Sessions Between Frameworks

【讨论】:

以上是关于Flask - 像使用 cookie 一样将会话数据保存在数据库中的主要内容,如果未能解决你的问题,请参考以下文章

jQuery cookie 是不是可以像会话变量一样过期?

烧瓶永久会话:在哪里定义它们?

Flask 会话忘记请求之间的条目

Flask – 具有相同名称的多个会话 cookie

在Flask和Flask-Login中删除会话cookie

Python Flask:跟踪用户会话?如何获取会话 Cookie ID?