Ruby on rails - 机架中间件排除 - 是否可能?

时间:2014-03-05 13:15:28

标签: ruby-on-rails ruby ruby-on-rails-3 rack middleware

我正在尝试使用机架中间件,在单独的层中进行身份验证。 问题是,所有请求都通过这一层。我不希望像css,javascript这样的资产请求通过身份验证中间件。 我也不希望注销流程通过这个。,

在application.rb

config.middleware.use AuthClient::MyFilterClass

我期待像

这样的东西
config.middleware.use AuthClient::MyFilterClass, :exclude => [:logout,'*/assets/*']

有没有办法从中间件中排除自定义路径/操作?

2 个答案:

答案 0 :(得分:8)

机架中间件形成一个向上和向下堆栈,如下例所示:

rack middleware

这意味着无论您提出什么要求,无论如何都会通过所有中间件 所以你不能排除这样的中间件。

您可以做的是将您自己的中间件注入堆栈,这将检查请求路径并调用其他一些中间件。

这样的事情:

class MyMiddleware
  def initialize(app)
    @app = app
  end

  def call(env)
    if env['REQUEST_PATH'].match(/^\/assets\//)
      middleware = AuthClient::MyFilterClass.new(@app)
      env = middleware.call(env)
    end

    @app.call(env)
  end
end

这将根据请求路径有条件地调用AuthClient::MyFilterClass中间件。

答案 1 :(得分:0)

这是我的发现,在处理这个问题时:

  1. 机架中间件没有处理排除模式/排除动作注入的可行性。
  2. 我同意Damien MATHIEU。在极端情况下,我们可以通过基于请求对象的过滤来实现。 这是我的代码示例:

    def call(env)
      if (should_authenticate(env))
        //do auth related stuff
      end
    
      @app.call(env)
    end
    
    private
      def should_authenticate(env)
        request = Request.new(env)
        return false if request.content_length.zero?
       strategy = other_conditions(env)
       return false unless strategy
    
    case strategy
    when 'condition1'
      //conditional logic
    when 'condition2'
      //conditional logic
    else
      false
    end
    end
    
    def other_conditions(env)
     if env['REQUEST_PATH'].match(/^\/assets\//)
       return 'condition1'
     end
    //Check for other pre-validations to do
    end