强参数和attr_accessible
向 Rails“批量分配”功能添加安全保护的两种不同方式。强参数是当前版本的 Rails 规定的方式。
“批量赋值”是 Rails 中一种方便的简写,它允许您在单个语句中设置模型的许多属性。
例如,假设您有一个@user
要使用来自表单提交的数据进行更新的对象。如果没有批量分配,您将不得不编写如下乏味的代码:
@user.first_name = params[:user][:first_name]
@user.last_name = params[:user][:last_name]
@user.phone_number = params[:user][:phone_number]
...
@user.save
并且在每个表单域上不断。
通过批量分配,所有代码都变成了一行:
@user.update(params[:user])
但是,这充满了安全漏洞。由于params
包含浏览器提交的任何数据,恶意用户可以向该提交添加您未预料到的数据。例如,他们可以添加is_admin=1
参数。如果你有一个is_admin
数据库列,那么批量分配只是让用户升级为管理员。哎呀!
这就是强参数的用武之地。使用强参数,ActiveModel::ForbiddenAttributesError
如果你尝试做 naïve ,Rails 会引发 a update(params[:user])
。相反,您需要使用Strong Parameters 提供的require
和帮助器明确说明您期望从浏览器提交中获得哪些参数。permit
像这样:
def user_params
# Note that :is_admin is not permitted!
params.require(:user).permit(:first_name, :last_name, :phone_number)
end
...
@user.update(user_params)
我不能代表 Rails 的维护者,但我喜欢 Strong Parameters,因为它很灵活。如果我在用户控制器中有多个需要不同参数的操作,我可以很容易地描述使用permit
应该允许的参数。
或者,如果我有不同的用户角色可以更新不同的属性,那么我可以轻松地为这些权限建模。正如@CV-Gate 提到的,您甚至可以在运行时更改这些权限,这是一个强大的功能。
简而言之,强参数的灵活性是由于您可以user_params
在任何地方定义该方法,并且您可以随意定义。您拥有 Ruby 和 OO 概念的全部力量,可以让它按照您想要的方式工作。
怎么样attr_accessible
?
无需过多介绍(因为 Rails 不再支持此功能):您可以在模型本身中使用宏permit
来做类似的事情,而不是使用该方法,如下所示:attr_accessible
class User < ActiveRecord::Base
attr_accessible :first_name, :last_name, :phone_number
...
end
所以对于简单的情况,它的工作方式与强参数非常相似;您只需在不同的地方定义属性列表。
但是,由于attr_accessible
模型类的定义是强耦合的,因此失去了很多灵活性。如果您有两个不同的控制器动作需要为同一User
模型进行质量分配怎么办?现在你被卡住了。
attr_accessor
该attr_accessor
宏内置于 Ruby 中,与 Rails、批量赋值或安全性无关。它只是碰巧有一个相似的名字。:)