我们的 Django 应用程序具有以下 session 管理要求。
- 当用户关闭浏览器时 session 过期。
- session 在一段时间不活动后过期。
- 检测 session 何时因不活动而过期并向用户显示适当的消息。
- 在不活动期结束前几分钟警告用户 session 即将到期。除警告外,还为用户提供延长 session 的选项。
- 如果用户在应用内处理不涉及向服务器发送请求的长时间业务事件,则 session 不得超时。
在阅读了文档、Django代码和一些与此相关的博文之后,我想出了以下实现方法。
要求 1
通过将 SESSION_EXPIRE_AT_BROWSER_CLOSE 设置为 True,可以轻松实现此要求。
要求 2
我看到了一些使用 SESSION_COOKIE_AGE 设置 session 到期期限的建议。但是这种方法存在以下问题。
session 总是在 SESSION_COOKIE_AGE 结束时过期,即使用户正在积极使用应用程序。 (这可以通过使用自定义中间件将每个请求的 session 到期设置为 SESSION_COOKIE_AGE 或通过将 SESSION_SAVE_EVERY_REQUEST 设置为 true 来保存每个请求的 session 来防止。但是由于使用了 SESSION_COOKIE_AGE,下一个问题是不可避免的。)
由于 cookie 的工作方式,SESSION_EXPIRE_AT_BROWSER_CLOSE 和 SESSION_COOKIE_AGE 是互斥的,即 cookie 在浏览器关闭或指定的到期时间到期。如果使用了 SESSION_COOKIE_AGE 并且用户在 cookie 过期之前关闭了浏览器,则 cookie 被保留,重新打开浏览器将允许用户(或其他任何人)进入系统而无需重新验证。
Django 仅依靠存在的 cookie 来确定 session 是否处于事件状态。它不会检查与 session 一起存储的 session 到期日期。
以下方法可用于实现此要求并解决上述问题。
- 不要设置 SESSION_COOKIE_AGE。
- 在每个请求上将 session 的到期日期设置为“当前时间 + 不活动期”。
- 覆盖 SessionMiddleware 中的 process_request 并检查 session 是否过期。如果 session 已过期,则丢弃 session 。
要求 3
当我们检测到 session 已经过期时(在上面的自定义 SessionMiddleware 中),在请求上设置一个属性来指示 session 过期。此属性可用于向用户显示适当的消息。
要求 4
使用 JavaScript 检测用户不活动,提供警告以及延长 session 的选项。如果用户希望延长 session ,请向服务器发送保活脉冲以延长 session 。
要求 5
使用 JavaScript 检测用户事件(在长时间的业务操作期间)并向服务器发送保持事件脉冲以防止 session 过期。
上面的实现方法看起来很复杂,我想知道是否有更简单的方法(特别是对于要求 2)。
任何见解都将受到高度赞赏。
最佳答案
我刚开始使用 Django。
如果登录的用户关闭浏览器或处于空闲状态(不活动超时)一段时间,我想让 session 过期。当我用谷歌搜索它时,首先出现了这个 SOF 问题。多亏了不错的答案,我查找了资源以了解中间件在 Django 的请求/响应周期中是如何工作的。很有帮助。
按照此处的最佳答案,我正准备将自定义中间件应用到我的代码中。但我还是有点怀疑,因为这里的最佳答案是在 2011 年编辑的。我花了更多时间从最近的搜索结果中搜索了一下,并想出了简单的方法。
SESSION_EXPIRE_AT_BROWSER_CLOSE = True
SESSION_COOKIE_AGE = 10 # set just 10 seconds to test
SESSION_SAVE_EVERY_REQUEST = True
除了chrome,我没有检查其他浏览器。
- 即使设置了 SESSION_COOKIE_AGE,当我关闭浏览器时 session 也会过期。
- 只有当我空闲超过 10 秒时,A session 才过期。感谢 SESSION_SAVE_EVERY_REQUEST,每当您发生新请求时,它都会保存 session 并更新超时以过期
要更改此默认行为,请将 SESSION_SAVE_EVERY_REQUEST 设置设置为 True。当设置为 True 时,Django 将在每次请求时将 session 保存到数据库中。
请注意, session cookie 仅在创建或修改 session 时发送。如果 SESSION_SAVE_EVERY_REQUEST 为 True, session cookie 将在每个请求上发送。
同样, session cookie 的过期部分在每次发送 session cookie 时都会更新。
我只是留下答案,这样一些像我这样的 Django 新手就不会像我一样花太多时间来寻找解决方案。
关于python - 如何由于 Django 中的不活动而使 session 过期?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3024153/