提问人:Nathan Thomas 提问时间:10/4/2023 更新时间:10/11/2023 访问量:29
Rails 5(来自 Rails 4.2)和 Devise 4(来自 Devise 3)升级: 在请求环境中找不到 Warden::P roxy 实例
Rails 5 (from Rails 4.2) and Devise 4 (from Devise 3) Upgrade: Warden::Proxy Instance Not Found in Request Environment
问:
因此,我们正在升级一个旧的 Rails 4 应用程序。我们目前正在尝试从 Rails 4.2 跳到 5.0。其中一部分涉及将 Devise 从版本 3 升级到版本 4。我们在版本 4 中跳得很晚,因为这应该与 Rails 5 兼容,至少根据文档和 railsbump.org
到目前为止,捆绑包安装成功并且服务器启动,但是访问任何页面都会导致一些错误,我们无法弄清楚这些错误:
Error during failsafe response: Devise could not find the `Warden::Proxy` instance on your request environment.
Make sure that your application is loading Devise and Warden as expected and that the `Warden::Manager` middleware is present in your middleware stack.
If you are seeing this on one of your tests, ensure that your tests are either executing the Rails middleware stack or that your tests are using the `Devise::Test::ControllerHelpers` module to inject the `request.env['warden']` object for you.
/home/josh/.rbenv/versions/2.7.6/lib/ruby/gems/2.7.0/gems/devise-4.9.2/lib/devise/controllers/helpers.rb:143:in `warden'
/home/josh/.rbenv/versions/2.7.6/lib/ruby/gems/2.7.0/gems/devise-4.9.2/lib/devise/controllers/helpers.rb:126:in `current_user'
/home/josh/.rbenv/versions/2.7.6/lib/ruby/gems/2.7.0/gems/paper_trail-4.0.2/lib/paper_trail/frameworks/rails/controller.rb:19:in `user_for_paper_trail'
/home/josh/.rbenv/versions/2.7.6/lib/ruby/gems/2.7.0/gems/paper_trail-4.0.2/lib/paper_trail/frameworks/rails/controller.rb:65:in `set_paper_trail_whodunnit'
从堆栈跟踪中,我们可以看到current_user是从一些我们无法控制的paper_trail代码中调用的。我们可以在 ApplicationController 中重写有问题的 paper_trail 用户方法,并控制那里发生的情况。这使我们能够控制 current_user 和 user_signed_in 的所有实例?如果我们把所有这些注释掉,这样就不会使用这些方法,就不会有错误,页面就会加载。至少,这可以让我们在其他一些事情上取得进展,但显然,如果应用程序要正常运行,我们需要这些助手才能工作。
错误消息提到了测试,通过谷歌、ChatGPT 等围绕这个问题进行的大量研究也提到了测试。但这在测试环境中不会发生,我们相信这不是问题所在。
Warden::Manager 中间件也存在于应用的中间件堆栈中。
本期提出了一些有趣的想法。我们的应用正在使用自定义异常应用,但与提出该问题的用户不同,此应用不继承自 ApplicationController。注释掉此代码并不能解决问题。下面是自定义异常的代码,以防万一有人注意到它:
def call(env)
status = env["PATH_INFO"][1..-1]
if status == "404" || status == '422' || status == '500'
Rails.application.routes.call(env)
else
super
end
end
end```
答:
我们想通了这个问题。事实证明,Web 控制台中间件有一个错误,我们只需要将 Web 控制台的版本向前推进一些。错误消息非常令人困惑,因为某些事情在日志记录、Web 控制台和 design/warden 之间的中间件中发生的顺序
评论
Make sure that your application is loading Devise and Warden as expected and that the