2

私の Rails 3.1 アプリでは、アクセスを検証するために Rack Middleware を作成しました。アクセスが承認されない場合、ユーザーはページにリダイレクトされます。具体的には、ビューに既にあるページになります。routes.rb で次のように定義して、dummy.html.erb にリダイレクトしようとしているとします。

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

ページが私のコントローラーです。

次のことを試しましたが、リダイレクト ループに陥っているようです。

/lib にある My Rack ミドルウェア:

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 ミドルウェアを使用せずに、たとえばコントローラーのみを使用してリダイレクトが正常に行われるのを見てきましたが、アプリケーションを実行する前にミドルウェアでこれを行う必要があることに注意してください。

4

2 に答える 2

1

答えはとても簡単で、私はばかげていると感じました。問題は、/dummy などの場所にリダイレクトすると、Rack ミドルウェアを介して別のパスが発生し、AccessVerifier コードを何度も通過して /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 に答える