skip_before_filter ignora los condicionales

Estoy tratando de usar skip_before_filter solo si la aplicación está en modo de producción. (No quiero que mis instancias de desarrollo sean públicas y quiero que la aplicación detecte automáticamente en qué tipo de instancia se encuentra y muestre una pantalla de inicio de sesión cuando no esté en modo de producción). Entonces, mi controlador de aplicación tiene la siguiente línea:

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

Y el controlador para mostrar páginas tiene esta línea:

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

Y in_production es simplemente:

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

Me doy cuenta de que puede haber otras vías aquí, pero tengo curiosidad por saber por qué skip_before_filter parece ignorar el condicional y siempre se salta el before_filter. ¿Se me escapa algo?

preguntado el 09 de enero de 11 a las 01:01

Usando Rails 2.3.9 y la gema de autenticación Devise. -

3 Respuestas

Es un error de Rails (o al menos un comportamiento extraño indocumentado). Se rastrea aquí: https://github.com/rails/rails/issues/9703

En este hilo, puede encontrar una solución (retorcida).

En lugar de

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

escribir

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

Funcionó para mí.

contestado el 05 de mayo de 13 a las 22:05

Descubrí que la solución publicada por SmartLove en el escenario descrito presenta una especie de agujero de seguridad o un comportamiento inesperado. La línea

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

debido a la :only => :show, es anulación el before_filter existente definido en ApplicationController. Eso significa que todas las acciones de este controlador (por ejemplo: editar,: crear, etc.), excepto: mostrar uno, omitirán authenticate_user. filtrar.

Una posible solución es eliminar la cláusula: only y verificar la acción llamada dentro del método condicional. Por ejemplo:

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

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

Respondido 13 Feb 14, 17:02

No estoy seguro skip_before_filter acepta un :if parámetro, así que probaría esta sintaxis

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

Si aún no funciona, intente poner esto en su controlador de aplicación

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

Respondido el 09 de enero de 11 a las 04:01

Ese primer ejemplo funciona. Si no acepta un: if param, ¿por qué guarda silencio? - mancha

skip_before_filter toma una *filters array splat, por lo que no puede decir si hay argumentos inválidos. Me imagino que cuando se trata el símbolo, las claves hash no válidas se ignoran (o no se recuperan). - David Sulc

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.