使用 Django 会话存储登录用户

2024-04-23

我正在创建一个以 REST 为中心的应用程序,它将针对大多数特定于域的模型使用某种 NoSQL 数据存储。对于我打算围绕 REST 数据框架构建的主站点,我仍然希望对用户、计费信息和域数据模型范围之外的其他元数据使用传统的关系数据库。

有人告诉我,只有当我能够尽可能避免在同一请求上对 RDBMS 和 NoSQL 数据存储执行 I/O 时,这种方法才是一个好主意。

我的问题:

  1. 这是个好建议吗? (我假设是这样,但是如果第一个前提是错误的,那么剩下的这些问题就没用了。)
  2. 我想至少尽可能缓存登录的用户。是否可以使用 Django 会话以安全、可靠、正确且容错的方式执行此操作?理想情况下,我希望会话 API 成为一个安全的、直接的替代品,用于检索当前用户,并尽可能少地与用户表进行交互。我需要做哪些跑腿工作才能把一切连接起来?
  3. 如果这最终太麻烦了,那么在不使用 django-nonrel 的情况下将用户信息存储在 NoSQL 存储中(即完全消除 RDBMS)有多容易?自定义身份验证/授权后端可以做到这一点吗?

我正在考虑对我的应用程序使用相同的方法,我认为它通常是安全的,但需要特别小心来解决缓存一致性问题。

Django 通常的操作方式是,当收到请求时,会对会话表运行查询,以查找与请求中的 cookie 关联的会话。然后,当您访问request.user,对 User 表运行查询以查找给定会话的用户(如果有,因为 Django 支持匿名会话)。因此,默认情况下,Django 需要两个查询来将每个请求与一个用户关联起来,这是昂贵的。

Django 会话的一个好处是它可以用作键值存储,而无需扩展任何模型类(与难以使用其他字段扩展的 User 类不同)。所以你可以举个例子request.session['email'] = user.email在会话中存储附加数据。从某种意义上说,这是安全的,您从中读取的内容request.session字典肯定是您放在那里的内容,客户端无法更改这些值。所以你确实可以使用这种技术来避免查询 User 表。

为了避免查询 Session 表,您需要启用会话缓存(或将会话数据存储在客户端 cookie 中)django.contrib.sessions.backends.signed_cookies,这是安全的,因为此类 cookie 受到加密保护,不会被客户端修改)。

启用缓存后,您需要 0 次查询才能将请求与用户数据关联起来。但问题是缓存一致性。如果您使用带有直写选项的本地内存缓存(django.core.cache.backends.locmem.LocMemCache with django.contrib.sessions.backends.cached_db)会话数据将在每次修改时写入数据库,但如果它存在于缓存中,则不会从数据库中读取它。如果您有多个 Django 进程,这会带来问题。如果一个进程修改了会话(例如更改session['email']),其他进程仍然可以使用旧的缓存值。

您可以通过使用共享缓存(Memcached 后端)来解决这个问题,这保证了一个进程所做的更改对所有其他进程都是可见的。通过这种方式,您可以将对 Session 表的查询替换为对 Memcached 后端的请求,这应该会快得多。

将会话数据存储在客户端 cookie 中还可以解决缓存一致性问题。如果您修改 cookie 中的电子邮件字段,则客户端将来发送的所有请求都应该有一个新电子邮件。尽管客户端可以故意发送旧的cookie,但它仍然带有旧的值。这是否是一个问题取决于应用程序。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Django 会话存储登录用户 的相关文章

随机推荐