我有一个旧的、相当大的 Rails 应用程序,我需要升级到当前版本。它目前在 Rails 4.2.11 上运行。我现在已经成功升级了所有 gem,因此它运行 Rails 版本 5.0.7。我处于应用程序再次启动并且大部分工作正常的状态。在这样做的同时,我已将 devise gem 从版本 3.4.0 升级到 4.0.0,但我也尝试过 4.7.3。这对我的问题没有影响。
唯一不能正常工作的是身份验证。我可以加载登录屏幕并使用用户登录。登录成功,但随后我被重定向回主应用程序页面,而不是受保护的资源。
据我所知,Devise 会话并未保留在会话中,但我不明白为什么它不起作用。我在日志中没有收到任何错误。当我请求受保护的资源时,日志显示初始 401 错误,并且我们被重定向到登录表单(如预期)。成功登录后(我看到数据库中的sign_in_count增加),会重定向到主页,而不是受保护的资源。
我已将以下代码添加到主页控制器(我被重定向到的)的索引方法中:
class MainController < ApplicationController
def index
puts "Current Admin User: #{current_admin_user} nil: #{current_admin_user.nil?} signedIn: #{admin_user_signed_in?}"
# rest of the code omitted for simplicity
end
end
输出如下:
web_1 | [pid: 1] [c48b7285-3f9e-4cb7-94ba-64b6c9d9bd0e] Processing by MainController#index as HTML
web_1 | Current User: is nil: true signed_in: false
(简化的)routes.rb 文件如下所示:
root 'main#index'
devise_for :admin_users
namespace :admin do
constraints(CheckIp.new) do
devise_scope :admin_user do # a
root to: '/admin/main#index' # b
resources :main_admin, path: :main do
... # contains sub resources
end
end
end
end
I've added the lines a and b after the upgrade in the hope it fixes my issues, but I could not see any difference. My understanding is that the devise 4 should redirect to the root (line b) inside my scope, but this is not happening. I also tried to move the line a before the constraints check and again before the admin namespace. The results are the same in all cases.
路由按照定义的顺序具有优先级。
由于root 'main#index'
在文件顶部定义,Rails 在/
到达带有约束的第二条路由之前已经匹配了请求。
您所要做的就是将默认路线移至约束下方:
devise_for :admin_users
namespace :admin do
constraints(CheckIp.new) do
devise_scope :admin_user do # a
root to: '/admin/main#index' # b
resources :main_admin, path: :main do
... # contains sub resources
end
end
end
end
root 'main#index'
devise_scope
这样,如果约束或不产生匹配的路线,它就会“失败” 。
我终于找到了我的问题的原因。我对日志标记的中间件堆栈进行了一些修改,如下所示:
Rails.configuration.middleware.delete(ActionDispatch::Cookies)
Rails.configuration.middleware.delete(ActionDispatch::Session::CookieStore)
Rails.configuration.middleware.insert_before(Rails::Rack::Logger, ActionDispatch::Session::CookieStore)
Rails.configuration.middleware.insert_before(ActionDispatch::Session::CookieStore, ActionDispatch::Cookies)
这不再有效。因此,我暂时删除了日志标记,因为身份验证更重要。