【发布时间】:2011-03-02 17:39:48
【问题描述】:
我们的 Django 应用程序具有以下会话管理要求。
- 当用户关闭浏览器时会话过期。
- 会话在一段时间不活动后过期。
- 检测会话何时因不活动而过期并向用户显示适当的消息。
- 在不活动期结束前几分钟警告用户即将到期的会话。除警告外,还为用户提供延长会话的选项。
- 如果用户在应用内处理不涉及向服务器发送请求的长时间业务活动,则会话不得超时。
在阅读了文档、Django代码和一些与此相关的博文之后,我想出了以下实现方法。
要求 1
通过将 SESSION_EXPIRE_AT_BROWSER_CLOSE 设置为 True,可以轻松实现此要求。
要求 2
我看到了一些使用 SESSION_COOKIE_AGE 设置会话到期期限的建议。但是这种方法存在以下问题。
会话总是在 SESSION_COOKIE_AGE 结束时到期,即使用户正在积极使用应用程序。 (这可以通过使用自定义中间件将每个请求的会话到期设置为 SESSION_COOKIE_AGE 或通过将 SESSION_SAVE_EVERY_REQUEST 设置为 true 来保存每个请求的会话来防止。但是由于使用了 SESSION_COOKIE_AGE,下一个问题是不可避免的。)
由于 cookie 的工作方式,SESSION_EXPIRE_AT_BROWSER_CLOSE 和 SESSION_COOKIE_AGE 是互斥的,即 cookie 在浏览器关闭或指定的到期时间到期。如果使用 SESSION_COOKIE_AGE 并且用户在 cookie 过期之前关闭浏览器,则 cookie 会被保留,重新打开浏览器将允许用户(或其他任何人)进入系统而无需重新验证。
Django 仅依靠存在的 cookie 来确定会话是否处于活动状态。它不会检查与会话一起存储的会话到期日期。
以下方法可用于实现此要求并解决上述问题。
- 不要设置 SESSION_COOKIE_AGE。
- 在每个请求上将会话的到期日期设置为“当前时间 + 非活动期”。
- 覆盖 SessionMiddleware 中的 process_request 并检查会话是否过期。如果会话已过期,则丢弃会话。
要求 3
当我们检测到会话已经过期时(在上面的自定义 SessionMiddleware 中),在请求上设置一个属性来指示会话过期。此属性可用于向用户显示适当的消息。
要求 4
使用 JavaScript 检测用户不活动,提供警告以及延长会话的选项。如果用户希望延长会话,请向服务器发送保活脉冲以延长会话。
要求 5
使用 JavaScript 检测用户活动(在长时间的业务操作期间)并向服务器发送保持活动脉冲以防止会话过期。
上面的实现方法看起来很复杂,我想知道是否有更简单的方法(特别是对于要求 2)。
任何见解都将受到高度赞赏。
【问题讨论】:
-
+1 提供详细的解决方案
-
"由于 cookie 的工作方式,SESSION_EXPIRE_AT_BROWSER_CLOSE 和 SESSION_COOKIE_AGE 是互斥的,即 cookie 在浏览器关闭或指定的到期时间到期。如果使用 SESSION_COOKIE_AGE 并且用户在 cookie 之前关闭浏览器过期,cookie 被保留,重新打开浏览器将允许用户(或任何其他人)进入系统,而无需重新验证。”如果我错了,请纠正我,但在较新的 Django 版本中,这似乎不再适用? (至少 1.5+)
-
"Django 仅依靠存在的 cookie 来确定会话是否处于活动状态。它不会检查与会话一起存储的会话到期日期。"这是not true了。
-
2020年,第二个答案应该是公认的。当前接受的一个增加了已经在 Django 上实现的东西的复杂性。
标签: python django session cookies