机架中间件如何重定向到我的Rails应用程序中的视图

时间:2012-07-16 21:27:07

标签: ruby-on-rails-3.1 rack

在我的Rails 3.1应用程序中,我创建了一个Rack Middleware来验证访问权限。如果未批准访问权限,则会将用户重定向到页面。具体来说,它将是我在视图中已有的页面。假设我正在尝试重定向到dummy.html.erb,我在routes.rb中定义为

match '/dummy', to :'page#dummy'

页面是我的控制器。

我尝试了以下内容,但我似乎陷入了一些重定向循环。

My Rack中间件位于/ lib:

class AccessVerifier
  def initialize(app)
    @app = app
  end
  def call (env)
    #....
    #....do some type of verification here and redirect if fail verification
    #....
    [301, {"Location" => '/dummy', "Content-Type" => "text/html"}, []]
  end
end

在application.rb中我有

config.autoload_paths += %W(#{config.root}/lib)
config.middleware.use "AccessVerifier"

我也试过在我的中间件中调用一个控制器但是我又遇到了一些重定向循环。我从我的中间件类中调用控制器,如下所示:

  def call (env)
    ...
    status,headers,response=PageController.action("validateAccess").call(env)
  end

并在我的控制器中:

 class PageController < ApplicationController
   def validateAccess
     redirect_to :controller => 'page', :action => "dummy"
   end
   ...
 end

我已经看到在没有使用Rack Middleware的情况下成功完成重定向,例如仅使用控制器,但请注意我需要在应用程序运行之前在中间件中执行此操作。

2 个答案:

答案 0 :(得分:1)

答案很简单我觉得很傻。问题是,当我重定向到某个地方说/ dummy时,它会导致另一个通过Rack中间件并再次通过我的AccessVerifier代码重定向到/ dummy并重复执行此操作,从而导致重定向循环。为了解决这个问题,我通过检查传入路径是否包含在我的停靠点列表中(其中/ dummy位于该列表中)然后停止来强制停止点。这是伪代码中的一个例子

if path in ListOfAcceptableStoppingPoints
    @app.call(env)

这修复了重定向循环问题,但现在我质疑我的具体情况是否更好,不使用rake中间件,因为我发现现在我正在过滤其他东西,如资产。当然,我可以尝试通过并挑选出我认为需要允许通过的所有内容,但这似乎太乏味而且不正确。似乎最终,我需要在轨道级别进行过滤,而不是在机架级别进行过滤。

答案 1 :(得分:0)

我没有回答我的问题,直接回答你的问题。但是,我建议使用cancan gem来处理授权,而不是创建一个自行开发的解决方案。见https://github.com/ryanb/cancan