Warden auth失败后,Rails日志中没有状态代码

时间:2016-06-14 09:46:52

标签: ruby-on-rails logging rack warden

我已经使用--api标记设置了Rails 5(5.0.0.rc1)应用。它使用Warden进行身份验证。

一切正常,但是当Warden身份验证失败时,响应未被正确记录。日志看起来像这样:

Started GET "/widgets.json" for ::1 at 2016-06-14 11:38:20 +0000
Processing by WidgetsController#index as JSON
Completed   in 0ms (ActiveRecord: 0.0ms)

或者,在制作中:

I, [2016-06-14T14:12:54.938271 #17625]  INFO -- : [db39f895-eeb1-4861-91d0-5d52c124e37a] Completed   in 1ms (ActiveRecord: 0.0ms)

当然应该说Completed 401 Unauthorized in...,但无论出于何种原因,它都不知道响应的状态代码。

Warden身份验证错误正在发送到Rack兼容的ActionController::Metal派生控制器,非常简单:

class UnauthorizedController < ActionController::Metal
  include ActionController::Head

  def self.call(env)
    @respond ||= action(:respond)
    @respond.call(env)
  end

  def respond
    head :unauthorized
  end
end

它使用基本的head方法进行响应(无需渲染任何内容),因此可能与在常规Rails控制器中使用head的行为相同。但没有。

如果我尝试使用redirect_to ...render ...(包括相关模块之后),也会发生同样的事情。所以在Rack→Rails→Warden→Warden failure app(控制器)的某个地方,响应的状态代码丢失了。日志知道开始记录请求,并且知道它已被处理,因为它显然会吐出&#34;已完成...&#34; -line。但有些东西并没有正确连接。

有关如何解决此问题的任何想法?

2 个答案:

答案 0 :(得分:2)

Warden没有rails记录器。它只是抛出an exception and catch it, Warden提供了一种通过before_failure回调

处理此异常的方法
# config/inializers/warden_config.rb
Warden::Manager.before_failure do |env, opts|
  Rails.logger.info("401 Unuthorized")
end

答案 1 :(得分:1)

我认为您遇到的情况类似于https://github.com/roidrage/lograge/issues/67#issuecomment-601604344。这可能是Rails日志工具工作方式的限制。我认为控制器完成了对事件的处理,然后使Rails打印带有nil状态码的日志消息。但是随后Warden中间件突然出现并设置了正确的响应代码。您可以将include ActionController::Instrumentation添加到工具UnauthorizedController,但是您将看到另一个Warden请求的日志条目。