2

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

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

页面是我的控制器。

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

我的机架中间件位于 /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

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

4

2 回答 2

1

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

if path in ListOfAcceptableStoppingPoints
    @app.call(env)

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

于 2012-09-21T15:31:20.553 回答
-1

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

于 2012-09-05T16:11:59.433 回答