Mongoid:如何防止通过批量分配创建未定义的字段?

这是代码:

class M include Mongoid::Document field :name end params = { name: "foo", age: 20 } M.create(params) #=> # 

请注意, age未定义,但已保存。

这是有问题的(可能是DoS的来源),因为恶意用户可以在POST中添加任何参数,并且大字符串可以潜入未知字段。(例如name=foo&bogus=#{'x'*1000000}

到目前为止,除了attr_accessible我找不到任何东西,但是对于Mongoid来说并不是很好,因为你必须在所有模型中attr_accessiblefieldattr_accessible保持相同的字段名称。 不干。

我认为attr_accessible API非常适合ActiveRecord,因为有一个。 您没有明确定义模型(DRY)和b中的字段 保证不存在将不存在的字段保存到RDB的可能性。 但是对于Mongoid,我认为应该有比attr_accessible更好的解决方案。

请注意,有一个全局配置设置allow_dynamic_fields但它不是关于质量分配,所以它超出了本讨论的范围,但我认为它实际上应该是一个每个模型的宏,并且还应该注意质量分配。

你是如何处理这个问题的?

我总是在模型中使用attr_accessible 。 我很少发现自己包括所有可访问的字段。 通常总是有一些字段不能用于质量分配。 如果您经常需要包含每个属性,并且您担心重复:

 attr_accessible *fields.keys 

我为解决这个问题所做的是在我的模型中使用之前的保存回调:

 set_callback(:save, :before) do |doc| (doc.attributes.keys - fields.keys).each { |f| doc.unset(f) } end 

这样,即使有额外的属性,它们也会在保存之前被删除。