设计sign_in端点在第一次调用时返回格式错误的会话cookie,但在连续两次sign_in调用中工作正常

问题描述 投票:0回答:1

好的 我们有一个运行良好的应用程序。几周前,一位(现在是前)员工做出了相当大的改变,这似乎导致了一个相当奇怪的错误,我试图找出实际的问题是什么,当然也解决它。

简而言之,这是一个失败的场景:

发布登录并获取用户信息

在应用程序中,我们使用 devise(我相信是 4.6.2)来验证用户身份,使用 CanCanCan 来授权资源,并使用 Ahoy 来跟踪某些类型的用户(在本例中为管理员)。

对于我们遇到的失败,我们有两条相关的路线:

  1. /users/sign_in
    <- This is a devise route
  2. GET /user
    <- This is a route which returns some relevant information regarding the current user including the user role and a JWT 令牌,他们可以使用它来执行 API 调用

GET /user
端点在控制器内部定义:
UsersController < V2::ApplicationController
,应用程序控制器中有一些钩子,相关的是:
before_action :authenticate_user!, :update_current_session
,其中
update_current_session
看起来像这样:

def current_session
    return unless current_user
    @current_session ||= current_user.sessions.find_by_session_id(cookies.signed[:_session_id])
end

def update_current_session
    return unless current_session
    current_session.accessed!(request)
end

所以据我了解,

authenticate_user!
使用devise,然后调用update_current_session函数。

Happy Flow - 之前的运作方式:

我们有一些内部测试/脚本需要

/user
返回的令牌,因为它们对我们的应用程序执行 API 调用。因此他们做了以下事情:

  1. 使用如下所示的正文对
    /users/sign_in
    执行 POST 调用
{ "user": { "email": "[email protected]", "password": "whatever" } }

    获得 200 OK 响应正文
  1. success: "true"
  2. 这会设置一些 cookie(响应有一些
  3. Set-Cookie
     标头:
Set-Cookie: ahoy_visit=[REDACTED]; path=/; expires=Mon, 20 Apr 2020 13:34:21 GMT; HttpOnly Set-Cookie: _session_id=[REDACTED]; path=/; expires=Mon, 20 Apr 2020 10:34:21 GMT; HttpOnly Set-Cookie: st_session=[REDACTED]; path=/; expires=Wed, 20 May 2020 09:34:21 GMT; HttpOnly Set-Cookie: _safe_cookies__known_cookies=ahoy_visitor%7Cahoy_visit%7C_session_id%7Cst_session; path=/; expires=Thu, 18 Apr 2030 09:34:21 GMT; HttpOnly

    使用标头
  1. /user
     调用 GET 
    Cookie
    ,这只是所有这些 Set-Cookie 参数在一起(或者只是多个 
    Cookie
     标头,两者都有效
  2. 收到相关机构的 200 OK 响应。
总结:

    POST 登录 - 接收一组 cookie
  1. 使用 cookies 调用 GET /user
  2. 成功
变更后的失败

自从前雇员变更后,上述相关流程就失效了。目前的情况是这样的:

    POST 登录 - 接收一组 cookie
  1. 使用 cookies 调用 GET /user
  2. 收到401未经授权
在尝试找出问题所在(主要通过 Postman 和一些脚本)后,我注意到一些很奇怪的事情:

在第一次调用 POST

/users/sign_in

 时,
st_session cookie 似乎比以前更短。 如果我们连续调用 POST /users/sign_in
 两次,则流程有效:

    POST 登录 - 接收一组 cookie(st_session 似乎格式错误或丢失某些内容)
  1. 再次 POST 登录 - 接收一组 cookie(现在 st_session 看起来正常)
  2. 使用 cookies 调用 GET /user
  3. 工作 - 从服务器接收正确的响应

st_session

好像是因为
session_store.rb
里面的配置:

Rails.application.config.session_store :cookie_store, key: 'st_session', expire_after: (Rails.env.production? ? 1.hour : 1.month), secure: Rails.env.production?

总结

更改之前,以下流程运行正常:

    POST 登录 - 接收一组 cookie
  1. 使用 cookies 调用 GET /user
  2. 成功
更改后,流程失败并显示 401:

    POST 登录 - 接收一组 cookie
  1. 使用 cookies 调用 GET /user
  2. 收到401未经授权
连续调用sign_in两次有效:

    发布登录
  1. 再次POST登录
  2. 使用 cookies 调用 GET /user
  3. 工作 - 从服务器接收正确的响应
调试/找出问题所在

我查看了

devise.rb

 和我们的 
sessions_controller
,但 401 故障似乎发生在这些地方之外。

有人知道什么可能导致这个问题吗?我试图调试并找出问题所在,但似乎无法取得相关进展。这似乎与 Devise/Warden 有关,但我不太熟悉那里发生的事情。

我更想知道谁存储了

st_session

 cookie 以及 
what 存储在其中,因为看起来第一次丢失某些东西(因为 st_session)更短,而且看起来 devise 无法正确根据该值对用户进行身份验证。

感谢任何帮助,甚至指导我到代码中的相关位置,我可以寻找答案/帮助调试

谢谢你。

ruby-on-rails devise ruby-on-rails-5 warden
1个回答
0
投票
我遇到了类似的问题,这是由 Devise 的

:timeoutable

 引起的

如果您的

current_user

 中有任何 
ApplicationController
 调用,它们将触发身份验证过程。

由于会话超时,在到达会话控制器中的登录代码之前会触发 401 错误。

我的解决方案是将以下行添加到会话控制器:

prepend_before_action :reset_session, only: [:create]


    

© www.soinside.com 2019 - 2024. All rights reserved.