我正在从Devise repo上的一个问题中转移这一点,因为我还不知道它实际上是一个bug。我希望有人能帮助我理解为什么我的设计会议时间安排得这么快。
环境
Ruby 2.7.2轨道6.1设计4.7.3
当前行为
我的目标是在要求用户再次登录之前,将会话持续大约30天。有了股票设计,我在桌面浏览器上看到了正确的持续会话时间,但在移动设备上看到了短会话(几天,有时几个小时(。我意识到也许我需要使用:timeoutable
我根据用户模型安装了:timeoutable
,在devise.rb中启用并设置了config.timeout_in
,时间为29.days。除了现在配置了:timeoutable
而不是更长的29.days会话外,所有浏览器会话都会在一两个小时后关闭。
预期行为
会话应持续29天,然后要求用户再次登录。
我觉得我错过了一些显而易见的东西,但我找不到。:timeoutable
不是实现这一点的正确方法吗?
更新:
将我的应用程序从子域移动到根域后,此问题自行解决。这并不是一个真正的答案,但我想在这里添加它作为上下文。除此之外,我认为下一个最好的答案是调整rails本地cookie商店。
无论如何,我仍然不相信timeoutable是否正常工作。
会话非常令人困惑,因为我们用同一个术语来表示很多不同的东西。
第一个是Rails提供的低级别ActionDispatch::Session
机制。它由一组中间件组成,该中间件将会话标识符(根据请求标识连接到应用程序的客户端(与会话存储链接起来。这确实可以在请求之间持久化任何类型的简单可序列化对象,虽然它最常用于身份验证,但它也可以做其他事情,如flash消息。
默认的会话存储是ActionDispatch::Session::CookieStore
,因为它是迄今为止速度最快的,但也有几个选项可以将会话数据存储在服务器上。您通过以下方式设置会话存储cookie的到期时间:
Rails.application.config.session_store :cookie_store, expire_after: 30.days
然后是所谓的身份验证会话,它实际上只是在存储中存储一个声明(一个id(,这样用户就不必在每个请求中提供凭据(电子邮件、密码(。在Devise,所有这些东西都由典狱长宝石处理。当您登录时,Warden会将该用户id填充到会话存储中,并在您注销时将其删除。使用特定客户端时,这会使您登录/注销。默认情况下,这里没有实际的超时——它的持续时间与会话存储cookie的持续时间一样长。
这就是Timeoutable模块的用武之地。它会在id的同时存储一个额外的时间戳,如果时间戳已经过期,Warden将拒绝存储在会话中的用户id并将其删除。请注意,如果cookie在此之前真的过期了,整个过程就没有意义了。
您可以简单地将其添加到您的用户模型中:
devise :timeoutable, timeout_in: 29.days
timeout_in
定义用户可以不活动以再次请求凭证的时间量。也就是说,只有当用户在29天内没有与他的应用程序交互时,用户会话才会过期。
请记住,要使用:timeoutable
,不需要额外的列,这对remember_me
不起作用。
更多细节:超时