如何在Ruby-On-Rails批量分配中禁止分配一个或多个字段?

时间:2012-07-06 00:23:51

标签: ruby-on-rails

我对这个质量分配问题有点困惑。这是我的问题

假设我有一个具有以下属性的用户模型: 名称 登录 密码 电子邮件

在编辑过程中,会触发更新方法:

def update
  @user = User.find(params[:id])
  if @user.update_attributes(params[:user]) 
   ....
end

在我看来,保护大多数(如果不是全部)这些属性是有意义的,因为我不希望密码/电子邮件/登录被泄露。所以我会在模型中做到这一点

attr_accessible:name

因此,除名称之外的所有其他属性都无法进行批量分配。

如果我这样做,有效的编辑表单会如何工作?我是否需要在更新方法@ user.email = params [:user] [:email]等中逐个分配属性?或者我误解了某些事情(可能)?

谢谢!

编辑:

更具体一点:

通常您会看到admin属性受保护的示例。这是有道理的。

但是密码或电子邮件属性呢?那些通常不受保护。为什么不保护密码或电子邮件?这可能意味着可能有人可以重置电子邮件并重置密码或重置密码属性并获得对系统的访问权限,不是吗?

2 个答案:

答案 0 :(得分:1)

观看此视频广播http://railscasts.com/episodes/26-hackers-love-mass-assignment/

您正在以错误的方式考虑质量分配安全性。 attr_accessbile不会使密码值对公众开放(您将使用filter_parameter来隐藏该值)。

这样想,你有一个用户表单。您希望用户能够使用密码创建帐户,但您不希望他们能够将自己添加为管理员(他们可以通过SQL注入或操作POST参数来实现)。为防止这种情况发生,您可以添加:name,:password,:email to attr_accessible,并省略管理员字段。

答案 1 :(得分:0)

想法是过滤控制器中的参数as described here

class PeopleController < ActionController::Base
  # This will raise an ActiveModel::ForbiddenAttributes exception because it's using mass assignment
  # without an explicit permit step.
  def create
    Person.create(params[:person])
  end

  # This will pass with flying colors as long as there's a person key in the parameters, otherwise
  # it'll raise a ActionController::MissingParameter exception, which will get caught by 
  # ActionController::Base and turned into that 400 Bad Request reply.
  def update
    redirect_to current_account.people.find(params[:id]).tap do |person|
      person.update_attributes!(person_params)
    end
  end

  private
    # Using a private method to encapsulate the permissible parameters is just a good pattern
    # since you'll be able to reuse the same permit list between create and update. Also, you
    # can specialize this method with per-user checking of permissible attributes.
    def person_params
      params.required(:person).permit(:name, :age)
    end
end