Django——session技术
文章目录
本文接上文,session在上篇简单介绍过,我们这次来详细说一下。
Django 是支持匿名会话的。会话框架允许您基于每个站点访问者存储和检索任意数据。它在服务器端存储数据并提供cookie的发送和接收。Cookie包含会话ID - 而不是数据本身(除非您使用基于cookie的后端)。Django会话框架完全是基于cookie的。
七、打开会话
会话通过配置一个中间件实现的,为了打开会话,需要做下面的操作
- 编辑设置中的 MIDDLEWARE,并确保他包含了 ‘django.contrib.sessions.middleware.SessionMiddleware’。通过 django-admin startproject 创建的默认 settings.py 文件是已经打开了 SessionMiddleware 这项设置的。
如果你不想使用会话功能,你可以从配置的 MIDDLEWARE 中删除 `SessionMiddleware,并且从 INSTALLED_APPS 中删除 ‘django.contrib.sessions’。它将会为您节省一点开销。
八、配置会话(session)引擎
默认情况下,Django 在数据库里存储会话(使用 django.contrib.sessions.models.Session
)。虽然这很方便,但在一些设置里,在其他地方存储会话数据速度更快,因此 Django 可以在文件系统或缓存中配置存储会话数据。
1. 使用数据库支持的会话(默认)
如果你想使用数据库支持的会话,你需要在INSTALLED_APPS
里添加 'django.contrib.sessions'
。
一旦在安装中配置,运行 manage.py migrate
来安装单个数据库表来存储会话数据。
2. 使用缓存会话
为了得到更好的性能,你可以使用基于缓存的会话后端。
使用 Django 的缓存系统来存储会话,你首先需要确保已经配置了缓存.
警告:如果你正在使用 Memcached 缓存后端,则应该只使用基于缓存的会话。本地内存缓存后端保留数据的时间不足以成为一个好的选择,直接使用文件或数据库会话而不是通过文件或数据库缓存后端发送所有内容会更快。另外,本地内存缓存后端并不安全,因此对生产环境来说或许不是一个好的选择。
如果你在CACHES
定义了多缓存,Django 会使用默认缓存。如果要使用其他缓存,请将SESSION_CACHE_ALIAS
设置为该缓存名。
一旦配置好了缓存,你有两种办法在缓存中存储数据:
- 设置
SESSION_ENGINE
为"django.contrib.sessions.backends.cache"
用于简单缓存会话存储。会话数据直接被存储在缓存里。然而,会话数据可能不是长久的:因为缓存满了或者缓存服务重启了,所以缓存数据会被收回。 - 为了持久化缓存数据,设置
SESSION_ENGINE
为"django.contrib.sessions.backends.cached_db"
。这使用直写式缓存——每次写入缓存的数据也会被写入到数据库。如果数据不在缓存中,会话仅使用数据库进行读取。
这两中会话存储会非常快,但简单缓存会更快,因为它忽略了持久化。在大部分情况下,cached_db
后端将足够快,但如果你需要最后一点的性能,并且愿意不时地删除会话数据,那么 cache
后端适合你。
3. 使用基于文件的会话
要使用基于文件的会话,需要设置SESSION_ENGINE
为 "django.contrib.sessions.backends.file"
你可能想设置SESSION_FILE_PATH
(默认从 tempfile.gettempdir()
输出,很可能是 /tmp
) 来控制 Django 存储会话文件的路径。要确保 Web 服务器有权限读取这个地址。
4. 使用基于cookie的会话
要使用基于cookies的会话,需要设置SESSION_ENGINE
为 "django.contrib.sessions.backends.signed_cookies"
。这个会话数据将使用 Django 的加密工具(cryptographic signing) 和SECRET_KEY
工具进行保存。
警告:
如果 SECRET_KEY 泄露了,并且你正在使用
PickleSerializer
] ,这会导致任意远程代码执行。拥有
SECRET_KEY
的攻击者不仅可以生成站点信任的伪造会话数据,也可以远程执行任意的代码,因为数据是使用 pickle 序列化的。如果你使用基于 cookie 的会话,一定要注意对于任何可能远程访问的系统,密钥是完全保密的。
会话数据已签名但未被加密
当使用cookie后端时,会话数据可以被客户端读取。
MAC(消息验证代码) 被用来保护数据不被客户端修改,因此会话数据在被篡改时失效。如果存储cookie 的客户端 (比如浏览器) 不能存储所有会话数据并丢弃数据,则会同样发生失效。即使 Django 压缩数据,它仍然完全有可能每个 cookie 超过4096字节的通用限制。
不保证新鲜度
注意虽然 MAC 可以保证数据(通过站点生成,而不是其他人)真实性和数据完整(它是完整和正确的),但它不能保证新鲜度,也就是说,您最后发送给客户端的东西会被退回。这意味着cookie后端为了使用一些会话数据,可能会面临重播攻击。与其他会话后端(每个会话保持服务端记录,并且当用户退出时使会话失效)不同,基于cookie的会话在用户退出的时候并不会让会话失效。因此攻击者窃取用户cookie,即使用户登出了,攻击者还可以使用cookie登录该用户。如果 Cookie 比
SESSION_COOKIE_AGE
设置的时间还旧时,则cookie会被检测为 ‘陈旧’ 。性能
最后,cookie的大小会影响网站的速度。
九、在视图中使用会话
当激活 SessionMiddleware
后,每个HttpRequest
对象(任何 Django 视图函数的第一个参数) 将得到一个 session
属性,该属性是一个类字典对象。
你可以在视图中任意位置读取它并写入 request.session
。你可以多次编辑它。下面是他的全部方法:
-
__getitem__
(key)比如:
fav_color = request.session['fav_color']
-
__setitem__
(key, value)比如:
request.session['fav_color'] = 'blue'
-
__delitem__
(key)比如:
del request.session['fav_color']
。如果给定的key
不在会话里,会引发KeyError
。 -
__contains__
(key)比如:
'fav_color' in request.session
-
get
(key, default=None)比如:
fav_color = request.session.get('fav_color', 'red')
-
pop
(key, default=__not_given)比如:
fav_color = request.session.pop('fav_color', 'blue')
-
keys
() -
items
() -
setdefault
() -
clear
()
它也有以下方法:
-
flush
()删除当前会话和会话cookie。如果你想确保早先的会话数据不能被用户的浏览器再次访问时,可以使用这个方法(比如
django.contrib.auth.logout()
函数调用它)。 -
set_test_cookie
()设置一个测试cookie来确定用户的浏览器是否支持cookie。由于测试通过,你不需要在下一个页面请求时再次测试它。
-
test_cookie_worked
()返回
True
或Fal