用户的登录状态放在哪里?每个请求为它付出多少次查询?过期了会被自动清掉吗?这篇看默认的数据库 session 后端,把创建时机、表内容、cookie 属性、查询数和过期都验证一遍。
GET /nothing/ Set-Cookie: False session 表行数: 0 GET /ro/ Set-Cookie: False session 表行数: 0 GET /read/ Set-Cookie: False session 表行数: 0 GET /set/ Set-Cookie: True session 表行数: 1
这也是「不登录的访客不产生 session 行」的原因;但一旦有代码往 session 里写(比如 messages 框架、CSRF 用 session 时),就会给每个访客创建一行。
session_key 长度 = 32 expire_date 距现在 = 14.0 天
session_data(前 60 字符)= eyJjYXJ0IjpbMSwyLDNdfQ:1xBtdR:nx5w9m_N2jjqQWTShcikaHgR1Vwbc7 …
解码后: {'cart': [1, 2, 3]}
Cookie 属性: {'httponly': True, 'samesite': 'Lax', 'max-age': 1209600, 'path': '/'}session_data 的格式是「base64 的 JSON : 时间戳 : 签名」(实测),所以数据库里的内容不能被随便伪造,但也不是加密的(base64 可读)。
/read/(只读):查询 = 1
SELECT "django_session"."session_key", "django_session"."session_data", "django_session"."expire_dat
/set/(修改):查询 = 4
SELECT "django_session"."session_key", "django_session"."session_data", "django_session"."expire_dat
BEGIN
UPDATE "django_session" SET "session_data" = 'eyJjYXJ0IjpbMSwyLDNdfQ:1xBtdS:1D6ER3uNfryST9BtuJ4_Ai4R
COMMIT
/nothing/(不访问 session):查询 = 0Django 会在响应阶段判断 session.modified,才决定是否写库。
SESSION_COOKIE_AGE = 1209600 秒 = 14 天;SESSION_SAVE_EVERY_REQUEST = False ;SESSION_COOKIE_HTTPONLY = True ;SESSION_COOKIE_SAMESITE = Lax ;SESSION_EXPIRE_AT_BROWSER_CLOSE = False
要「用户活跃就续期」需要 SESSION_SAVE_EVERY_REQUEST = True(每个请求都写库,本文没有测它的代价)。
过期后表里行数: 1 ; 用该 cookie 读取: {'cart': None}
clearsessions 之后表里行数: 0数据库后端的表会一直增长。定时任务运行 clearsessions(cron / celery beat)。缓存后端靠缓存自己的过期。