无论修改时间如何,都会使Django会话失效

时间:2016-06-24 03:51:50

标签: django session

来自Django's documentation for set_expiry

  

读取会话不会被视为过期目的的活动。会话到期时间是从会话修改的最后一次计算出来的。

Django SESSION_COOKIE_AGE设置的默认值为1209600(2周,以秒为单位)。因此,如果会话在1月1日午夜创建,它将设置为在1月15日午夜到期。但是,如果该会话在1月14日午夜被修改,那么它将在1月28日午夜而不是原来的1月15日午夜到期。

我对两周的默认生命周期感到满意,但我想知道最有效的方法,因此所有会话在创建后的两周内都会过期 - 即使它们被修改。似乎我必须编写一些中间件来检查会话创建时间,然后将到期时间设置为两周后,但似乎必须有一种比这更有效的方法。

1 个答案:

答案 0 :(得分:2)

您应该扩展django.contrib.session.backends.db.SessionBase类并修改行为,因此只需快速查看该类,您就可以查看save(...)get_expiry_date(...)方法。

以下是自定义会话存储类的示例,如果已存在具有该密钥的会话,则不会更新会话的expiry_date

from django.contrib.sessions.backend.db import SessionStorage

class MySessionStore(SessionStore):
    def save(self, must_create=False):
        """
        Saves the current session data to the database. If 'must_create' is
        True, a database error will be raised if the saving operation doesn't
        create a *new* entry (as opposed to possibly updating an existing
        entry).
        """
        if self.session_key is None:
            return self.create()
        existing_session = Session.objects.filter(session_key=self.session_key)
        expire_date = self.get_expiry_date()
        if existing_session.exists():
            #  Here we select the original expire_date from the database
            #  so when the session is modified and saved, expire_date
            #  remains unchanged
            if existing_session.first().expire_date is not None:
                expire_date = existing_session.first().expire_date
        obj = Session(
            session_key=self._get_or_create_session_key(),
            session_data=self.encode(self._get_session(no_load=must_create)),
            expire_date=expire_date
        )
        using = router.db_for_write(Session, instance=obj)
        try:
            with transaction.atomic(using=using):
                obj.save(force_insert=must_create, using=using)
        except IntegrityError:
            if must_create:
                raise CreateError
            raise

现在我们有一个自定义会话类,每次修改会话时都不会更新到期日期,我们必须使用SESSION_ENGINE设置为SESSION_ENGINE='path.to.MySessionStore'的自定义会话类

我还没有测试过这个解决方案,我只是在回答一个问题:)