Django4.0 使用会话-配置会话(session)引擎
默认情况下,Django 在数据库里存储会话(使用 django.contrib.sessions.models.Session
)。虽然这很方便,但在一些设置里,在其他地方存储会话数据速度更快,因此 Django 可以在文件系统或缓存中配置存储会话数据。
使用数据库支持的会话
如果你想使用数据库支持的会话,你需要在 INSTALLED_APPS
里添加 django.contrib.sessions
。
一旦在安装中配置,运行 manage.py migrate
来安装单个数据库表来存储会话数据。
使用缓存会话
为了得到更好的性能,你可以使用基于缓存的会话后端。
使用 Django 的缓存系统来存储会话,你首先需要确保已经配置了缓存。
注意:如果您使用 Memcached 或 Redis 缓存后端,则应仅使用基于缓存的会话。 本地内存缓存后端保留数据的时间不足以成为一个好的选择,并且直接使用文件或数据库会话而不是通过文件或数据库缓存后端发送所有内容会更快。 此外,本地内存缓存后端不是多进程安全的,因此可能不是生产环境的好选择。
如果你在 CACHES
定义了多缓存,Django 会使用默认缓存。如果要使用其他缓存,请将 SESSION_CACHE_ALIAS
设置为该缓存名。
一旦配置好了缓存,你有两种办法在缓存中存储数据:
- 设置
SESSION_ENGINE
为 django.contrib.sessions.backends.cache
用于简单缓存会话存储。会话数据直接被存储在缓存里。然而,会话数据可能不是长久的:因为缓存满了或者缓存服务重启了,所以缓存数据会被收回。 - 为了持久化缓存数据,设置
SESSION_ENGINE
为 django.contrib.sessions.backends.cached_db
。这使用直写式缓存——每次写入缓存的数据也会被写入到数据库。如果数据不在缓存中,会话仅使用数据库进行读取。
这两中会话存储会非常快,但简单缓存会更快,因为它忽略了持久化。在大部分情况下,cached_db
后端将足够快,但如果你需要最后一点的性能,并且愿意不时地删除会话数据,那么 cache
后端适合你。
使用基于文件的会话
要使用基于文件的会话,需要设置 SESSION_ENGINE
为 django.contrib.sessions.backends.file
。
您可能还想设置 SESSION_FILE_PATH
(默认为从 tempfile.gettempdir()
输出,很可能是 /tmp
)来控制 Django 存储会话文件的位置。 请务必检查您的 Web 服务器是否有权读取和写入此位置。
使用基于cookie的会话
要使用基于cookies
的会话,需要设置 SESSION_ENGINE
为 django.contrib.sessions.backends.signed_cookies
。这个会话数据将使用 Django 的加密工具 cryptographic signing
和 SECRET_KEY
工具进行保存。
建议将 SESSION_COOKIE_HTTPONLY
设置为 True
来防止通过 JavaScript 访问存储数据。
警告
如果 SECRET_KEY
没有保密并且您正在使用 PickleSerializer
,这可能会导致任意远程代码执行。
拥有 SECRET_KEY
的攻击者不仅可以生成您的站点信任的伪造会话数据,还可以远程执行任意代码,因为数据是使用 pickle
序列化的。
如果您使用基于 cookie
的会话,请特别注意您的密钥始终完全保密,对于任何可以远程访问的系统。
会话数据已签名但未加密
使用 cookie
后端时,客户端可以读取会话数据。
MAC(Message Authentication Code)
用于保护数据不被客户端更改,从而使会话数据在被篡改时失效。如果存储 cookie
的客户端(例如您的用户的浏览器)无法存储所有会话 cookie
并丢弃数据,则会发生同样的失效。即使 Django 压缩了数据,仍然完全有可能超过每个 cookie 4096
字节的常见限制。
不保证新鲜
另请注意,虽然 MAC
可以保证数据的真实性(它是由您的站点生成的,而不是其他人生成的)和数据的完整性(它都在那里并且正确),但它不能保证新鲜度,即您将被退回您发送给客户的最后一件事。这意味着对于会话数据的某些用途,cookie
后端可能会使您面临重放攻击。与保留每个会话的服务器端记录并在用户注销时使其失效的其他会话后端不同,基于 cookie
的会话在用户注销时不会失效。因此,如果攻击者窃取了用户的 cookie
,即使用户注销,他们也可以使用该 cookie
以该用户身份登录。只有在您的 SESSION_COOKIE_AGE
之前,Cookie
才会被检测为“陈旧”。
性能
最后,cookie
的大小会影响您网站的速度。