我正在尝试使用机架中间件,在单独的层中进行身份验证。 问题是,所有请求都通过这一层。我不希望像css,javascript这样的资产请求通过身份验证中间件。 我也不希望注销流程通过这个。,
在application.rb
中config.middleware.use AuthClient::MyFilterClass
我期待像
这样的东西config.middleware.use AuthClient::MyFilterClass, :exclude => [:logout,'*/assets/*']
有没有办法从中间件中排除自定义路径/操作?
答案 0 :(得分:8)
机架中间件形成一个向上和向下堆栈,如下例所示:
这意味着无论您提出什么要求,无论如何都会通过所有中间件 所以你不能排除这样的中间件。
您可以做的是将您自己的中间件注入堆栈,这将检查请求路径并调用其他一些中间件。
这样的事情:
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)
这是我的发现,在处理这个问题时:
我同意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