为什么strong_parameters方法是私有的?

时间:2014-07-03 19:34:47

标签: ruby-on-rails ruby security ruby-on-rails-4 strong-parameters

rails scaffolds默认为resource_params方法提供私有方式:

private

def person_params
  params.require(:person).permit(:name, :age)
end

我理解为什么strong_parameters是一件好事。我也明白,这可以防止在控制器外部访问该方法,但是这个方法是否公开存在任何真正的危险,或者将此作为私有方法的原因是什么?能够从扩展ActionController的gem发送该方法到控制器会很好。

换句话说,为什么访问控制器外部的方法?例如,如果我有一个单独的控制器来处理授权,我想将一个实例变量传回给包含初始化对象的原始控制器。

3 个答案:

答案 0 :(得分:2)

因为不从任何外部对象调用此方法。 质量分配保护与“人员参数”方法可见性无关,它只是应用程序设计的最佳实践

控制器使用app设计只能处理一个请求。您不应该从另一个控制器中调用方法。如果要共享多个控制器的方法,可以使用继承,混合或服务对象

继承

class BaseController < ApplicationController
  private
  def shared_method
  end
end

class UsersController < BaseController
   def index
     shared_method
   end
end

混入

module SomeMixin
  extend ActiveSupport::Concern 
  included do
    def shared_method
    end
  end
end

class UsersController < ApplicationController
  include SomeMixin
   def index
     shared_method
   end
end

服务对象

class SomeService
   def shared_method(params)
     # process params
   end
end

class UsersController < ApplicationController
  include SomeMixin
   def index
     SomeService.new.shared_method(params)
   end
end

答案 1 :(得分:1)

这并不总是这样,它可以保护你。看看关于这个主题的这个伟大的blog post

以下是一些相关摘要:

  

批量分配问题:安全漏洞

     

质量分配使我们无需为每个属性赋值   该模型,但它可以产生问题。因为我们没有限制   我们可以设置哪些属性,也不检查这些属性的价值   属性,恶意黑客可以为任何值分配任何值   属性。在我们的例子中,他可以设置admin的值,   让自己成为超级用户。

     

这是网址的样子

     

http://www.example.com/user/signup?user[name]=ow3ned&user[admin]=1

如果用户对模型有所了解并导致问题,他们就可以利用这一点。

答案 2 :(得分:0)

在大多数语言中,类中包含方法,属性或其他任何可能包含的分类。

根据语言或继承,默认行为可能是公共的,私有的......

在ruby中,默认情况下,类包含公共方法和属性。您需要指定方法是否为私有。

公共方法或属性:
这可以从类或类的实例中访问。所以,如果你有课程:

class Foo
    def my_id
         10
    end

    private
        def my_class
             "Bar"
        end

    public
        def my_friend
             "Zonk"
        end
end

然后:

2.0.0p247 :001 > @foo = Foo.new

2.0.0p247 :002 > @foo.my_id
 => 10

2.0.0p247 :003 > @foo.my_class
NoMethodError: undefined method `my_class' for #<Foo:0x000000045a53f8>

2.0.0p247 :004 > @foo.my_friend
 => "Zonk"

你看,你可以随心所欲地从私人变为公众,但也许不是一个好主意。