2

我想检查用户输入哈希中的值(传递给 Rails 控制器的参数)。我想保护自己免受虚假用户输入的侵害。Object#try 可以防止我丢失输入,但是格式错误的输入呢?

简单,不安全的情况:

  if params[:credentials][:login] …

显然,如果用户没有提供 :credentials 值,那么我尝试获取 :login 将失败……Nil 没有方法 :[]。一个非常好的解决方案是 Object#try:

  if params[:credentials].try(:[], :login) … 

但是,如果问题是用户提供了格式错误的凭据怎么办?特别是,我的一个用户传递了一个数组,而不是一个哈希。所以我仍然得到一个例外,

TypeError: can't convert Symbol into Integer

有没有类似 try() 的东西,可以将任何 bogosity 变成 false/nil?

我能来的最接近的是

  if begin params[:credentials][:login]; rescue; false; end … 

这有点混乱——不过,我承认,它比明确的偏执狂更紧凑、更笼统:

  if (params.has_key? :credentials and params[:credentials].is_a? Hash and params[:credentials].has_key? :login) … 
4

1 回答 1

4

你不应该begin/rescue在这里使用语句,它会影响性能并且你的意图并不明确。与trywhich 相同,只是rescue nil变相。

您必须检查所有内容,并且检查正确。混合数据检查和逻辑有点丑陋。

自从看了 Avdi 的 Confident Ruby 之后,我改变了编码方式;我建议您执行类似的操作(我只是稍微简化了您的代码):

def your_action
  checked_params_for_action do
    #safe params here
    #your_controller_code
  end
end

private

def checked_params_for_action(&block)
  if (params[:credentials].is_a?(Hash) && params[:credentials][:login])
    yield
  else
    redirect_to root_path, error: "params malformed"
  end
end
于 2012-08-03T20:28:48.590 回答