我刚刚意识到当我使用基于文件的会话引擎时,我的会话不会过期。查看基于文件的会话的Django代码,Django不存储会话的任何过期信息,因此除非会话文件被手动删除,否则它永远不会过期。
这看起来像是一个错误,因为数据库支持的会话工作正常,我相信无论后端开发人员选择什么会话,他们都应该表现得相似。
切换到数据库支持的会话对我来说不是一个选项,因为我需要将用户的会话存储在文件中。
有人可以点灯吗? 这真的是个bug吗? 如果是的话,您如何建议我解决它?
谢谢!
答案 0 :(得分:3)
所以看起来你是对的。至少在django 1.4中,使用django.contrib.sessions.backends.file
完全忽略SESSION_COOKIE_AGE
。我不确定这是真的是一个错误,还是没有记录。
如果您确实需要此功能,可以根据contrib中的文件后端创建自己的会话引擎,但使用到期功能扩展它。
打开django/contrib/sessions/backends/file.py
并添加以下导入:
import datetime
from django.utils import timezone
然后,在load
方法中添加两行,使其显示如下:
def load(self):
session_data = {}
try:
session_file = open(self._key_to_file(), "rb")
if (timezone.now() - datetime.datetime.fromtimestamp(os.path.getmtime(self._key_to_file()))).total_seconds() > settings.SESSION_COOKIE_AGE:
raise IOError
try:
file_data = session_file.read()
# Don't fail if there is no data in the session file.
....
这实际上会比较会话文件上的最后修改日期以使其过期。
将此文件保存在您的项目中并将其用作SESSION_ENGINE
而不是'django.contrib.sessions.backends.file'
如果您希望会话根据不活动时间超时,您还需要在设置中启用SESSION_SAVE_EVERY_REQUEST
。
答案 1 :(得分:0)
选项是在存储会话的目录中使用tmpwatch
答案 2 :(得分:0)
我在Django 3.1
遇到了类似的问题。就我而言,我的程序在检查会话到期之前调用带有整数参数(数据类型为set_expiry(value)
的函数int
。
根据Django documentation,自变量value
到set_expiry()
的数据类型可以是int
,datetime
或timedelta
。但是,对于基于文件的会话,expiry check inside load()
仅在事先将int
参数传递给set_expiry()
时才不能正常工作,并且datetime
和{ timedelta
的{1}}自变量。
一种简单的解决方案(解决方法?)是避免将set_expiry()
的参数int
派生到set_expiry(value)
并覆盖django.contrib.sessions.backends.file.SessionStore
(下面的代码示例),然后在set_expiry(value)
SESSION_ENGINE
settings.py
注意:
将from datetime import timedelta
from django.contrib.sessions.backends.file import SessionStore as FileSessionStore
class SessionStore(FileSessionStore):
def set_expiry(self, value):
""" force to convert to timedelta format """
if value and isinstance(value, int):
value = timedelta(seconds=value)
super().set_expiry(value=value)
或timedelta
传递给datetime
也可以,但是您需要handle serialization issue on datetime
object。