2

我刚刚意识到,当我使用基于文件的会话引擎时,我的会话不会过期。查看基于文件的会话的 Django 代码,Django 不会为会话存储任何过期信息,因此除非手动删除会话文件,否则它永远不会过期。

这对我来说似乎是一个错误,因为数据库支持的会话工作正常,我相信无论后端开发人员选择什么会话,它们都应该表现得相似。

切换到数据库支持的会话对我来说不是一个选项,因为我需要将用户的会话存储在文件中。

任何人都可以发光吗?这真的是一个错误吗?如果是,你建议我如何解决它?

谢谢!

4

3 回答 3

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如果您希望会话根据不活动状态超时,您还需要在设置中启用。

于 2012-04-17T20:44:35.387 回答
0

一个选项是tmpwatch在存储会话的目录中使用

于 2012-04-17T20:58:14.263 回答
0

我遇到了类似的问题Django 3.1。就我而言,我的程序在检查会话到期之前set_expiry(value)使用整数参数(数据类型)调用该函数。int

根据Django 文档,参数的数据类型value可以set_expiry()int,datetimetimedelta. 但是,对于基于文件的会话,只有在预先将参数传递给的情况下,内部的到期检查load()才能正常工作,并且此类问题不会发生在.intset_expiry()datetimetimedeltaset_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可以set_expiry(value),但您需要处理datetimeobject的序列化问题。

于 2020-10-29T04:40:41.743 回答