2011-01-09 115 views
12

我只在應用程序處於生產模式時才試圖使用skip_before_filter。 (我不希望公開我的開發實例,我希望應用程序自動檢測它的實例類型,並在未處於生產模式時顯示登錄屏幕)。所以,我的應用程序控制器具有以下行:skip_before_filter忽略條件

before_filter :authenticate_user!, :except => "sign_in" #redirects to log-in 

而控制器用於顯示網頁有這一行:

skip_before_filter :authenticate_user!, :only => :show, :if => :in_production 
#public pages are public, but only when in production. 

而且in_production很簡單:

def in_production 
    ENV['RAILS_ENV']=='production' 
    end 

我認識到,有可能是其他途徑這裏,但我很好奇,爲什麼skip_before_filter似乎忽視了條件和永遠只是跳過的before_filter。有什麼我失蹤?

+0

使用Rails 2.3.9和Devise身份驗證gem。 – Smudge 2011-01-09 01:03:27

回答

17

這是一個Rails錯誤(或者至少是一個無證的奇怪行爲)。它被追蹤到這裏:https://github.com/rails/rails/issues/9703

在這個線程中,你可以找到一個(扭曲的)解決方案。取而代之的

skip_before_filter :authenticate_user!, :only => :show, :if => :in_production 

skip_before_filter :authenticate_user!, :only => :show 
before_filter  :authenticate_user!, :only => :show, :unless => :in_production 

它爲我工作。

4

我不知道skip_before_filter接受一個:if參數,所以我想嘗試這句法

(skip_before_filter :authenticate_user!, :only => [:show]) if in_production 

如果還是不行,請嘗試把這個應用程序中的控制器

if ENV['RAILS_ENV']=='production' 
    skip_before_filter :authenticate_user!, :only => :show 
end 
+0

第一個例子有效。如果它不接受:如果參數,它爲什麼對此保持沉默? – Smudge 2011-01-09 01:35:29

6

我發現SmartLove在上述場景中發佈的解決方案存在一種安全漏洞或意外行爲。行

before_filter :authenticate_user!, :only => :show, :unless => :in_production

因爲:only => :show的,被覆蓋現有的before_filter在ApplicationController中所定義。這意味着除了:show one之外,此控制器的所有操作(例如:edit,:create等)都將省略authenticate_user!過濾。

一種可能的解決方案是去除:僅子句和檢查稱爲條件方法內的動作。例如:

before_filter :authenticate_user!, :unless => :skip_filter? 

def skip_filter? 
    params[:action] == "show" && in_production 
end