为什么当会话超时时 devise 会重定向到当前路径

bra*_*ana 3 ruby-on-rails devise

这里的代码显示,当会话超时时,devise 将重定向到当前请求的路径(由模块检查和强制执行timeoutable): https: //github.com/plataformatec/devise/blob/master/lib/devise/failure_app .rb#L120

在调用失败应用程序之前attempted_path设置。warden

问题是:为什么要设计重定向回当前请求的路径本身?如果会话超时,那么客户端是否应该被重定向到当前实体(UserAdmin其他实体)的登录页面?

它确实使用了scope_urlifattempted_path未设置。但我不明白为什么要再次重定向到当前请求的路径?这不会导致重定向循环吗?

这个重定向循环实际上是在 Rails 管理中发生的。如果我启用timeoutable要在 Rails 管理中进行身份验证的模型,那么在会话超时后,任何请求都将导致重定向循环。

attempted_path那么有人可以向我解释为什么要进行重定向吗?坐服务什么用例?

附加信息 这是我想到的两个流程。

应该如何

  • 用户尝试访问页面 x。会话超时。
  • 用户被重定向到登录页面
  • 用户登录
  • 用户被重定向回页面 x

目前情况如何

  • 用户尝试访问页面 x。会话超时。
  • 用户被重定向到页面 x。

它会重复进入一个循环,直到浏览器显示“网站未正确重定向”。

bra*_*ana 5

经过漫长的“调试周末”后,我发现问题是因为 Session 和 Cookie 中间件放置在机架堆栈中的 Warden 之后。

我的应用程序是Rails 5 API应用程序,这意味着默认情况下cookie和会话不可用。尽管是一个 API 应用程序,但由于某些原因,我不得不合并基于会话/cookie 的身份验证机制。所以我手动将这两个中间件添加到机架堆栈中。

自从我添加它们以来,config/application.rb它们几乎被添加到堆栈的远端,即在Warden中间件本身之后。然而,中间件非常清楚地表明它需要堆栈中的WardenSession 和 Cookie 管理器。before这样,它所做的任何会话更改最终都会序列化到会话和 cookie 中。

这导致失败应用程序所做的会话更改被丢弃。因此,会话从未被清除并导致重定向循环。以下步骤将使其更加清晰。

本来应该怎样

  1. 用户登录。会话是使用用户 ID 设置的。
  2. 用户使用。会话已使用用户 ID 进行更新。
  3. 用户空闲(至少在超时时间内)
  4. 用户提出请求。请求是通过同一会话发送的。
  5. 会话被识别为超时。清除会话并重定向回同一页面。
  6. 浏览器再次访问同一页面。
  7. 会话中没有用户。重定向到登录页面。

我的情况是如何发生的

  1. 用户登录。会话是使用用户 ID 设置的。
  2. 用户使用。会话已使用用户 ID 进行更新。
  3. 用户空闲(至少在超时时间内)
  4. 用户提出请求。请求是通过同一会话发送的。
  5. 会话被识别为超时。
  6. 会话被清除,但清除的会话永远不会序列化回 cookie。(发生这种情况是因为在身份验证失败的情况下,控制会直接返回到Warden中间件,绕过它所经过的所有中间中间件。因此它会错过 cookie 和会话中间件)
  7. 重定向回同一页面。浏览器保持会话 cookie 不变。
  8. 浏览器使用相同的会话 cookie 再次访问同一页面

重复步骤 5-8,直到浏览器因错误而停止。

这是我为任何对细节感兴趣的人制作的捕获整个流程的序列图。

设计超时流程

@Prometheous:谢谢您的评论。然而,有一件事我仍然不清楚:

如果超时,直接重定向FailureAppscope login url. 你说 :

如果没有重定向到尝试的路径,设计将不知道如何重定向到登录页面。

但是,它不能从此处部分scope_url使用的方法中获取它吗else: https: //github.com/plataformatec/devise/blob/master/lib/devise/failure_app.rb#L128

scope是肯定知道的。

我缺少什么?