Rails 什么时候应该使用强参数?
Rails When should I use strong parameters?
我不确定我是否正确理解了强参数的概念。我应该对仅用于编辑某些数据的参数使用强参数吗?或者我应该将它们用于我想要进入控制器的每个参数?例如我想获取两个日期之间的数据,所以我需要 date1 和 date2 作为参数。我应该在这里使用强参数吗?
了解何时应使用强参数的最简单方法是了解什么是批量分配自愿性。在 Rails 3 中,您可以执行以下操作:
class CreateUsers < ActiveRecord::Migration[3.0]
def change
create_table :users do |t|
t.string :email
t.string :encrypted_password
t.boolean :admin
t.timestamps
end
end
end
class UserController < ApplicationController
def create
@user = User.new(params[:user])
if @user.save
redirect_to @user
else
render :new
end
end
end
这里我们只是将一个“散列”(它实际上是一个 ActionController::Parameters 实例)直接传递到模型中。恶意用户在这里所要做的就是请求:
POST /users?users[admin]=1
并且他们已经创建了一个管理员帐户。 In 2012 Egor Homakov famously exploited one such loophole in Github 提交到 Rails 存储库。
使用 cURL 或使用网络检查器操纵表单可以轻松执行此类攻击。
如果我们将用户应该能够传递的属性列入白名单:
class UserController < ApplicationController
def create
@user = User.new(
params.require(:user)
.permit(:email, :password, :password_confirmation)
)
if @user.save
redirect_to @user
else
render :new
end
end
end
然后这就避免了漏洞 - 强参数实际上只是一个简单的 DSL,用于对嵌套哈希结构进行切片和切块。 Rail 4 中的变化是,当您将 ActionController::Parameters
的 n 个实例传递给模型时,会引发异常,除非对参数对象 returns true 调用 #permitted?
。这避免了由于程序员的懒惰或无知而导致的批量分配漏洞。
它不会以任何其他方式清理您的输入。例如,如果您不小心对待用户输入,它不会阻止 SQL 注入或远程代码执行。
如果像这个非常人为的示例中那样一个接一个地传递参数,则不需要强参数:
class UserController < ApplicationController
def create
@user = User.new do |u|
u.email = params[:user][:email]
u.password = params[:user][:password]
u.password_confirmation = params[:user][:password_confirmation]
end
if @user.save
redirect_to @user
else
render :new
end
end
end
我不确定我是否正确理解了强参数的概念。我应该对仅用于编辑某些数据的参数使用强参数吗?或者我应该将它们用于我想要进入控制器的每个参数?例如我想获取两个日期之间的数据,所以我需要 date1 和 date2 作为参数。我应该在这里使用强参数吗?
了解何时应使用强参数的最简单方法是了解什么是批量分配自愿性。在 Rails 3 中,您可以执行以下操作:
class CreateUsers < ActiveRecord::Migration[3.0]
def change
create_table :users do |t|
t.string :email
t.string :encrypted_password
t.boolean :admin
t.timestamps
end
end
end
class UserController < ApplicationController
def create
@user = User.new(params[:user])
if @user.save
redirect_to @user
else
render :new
end
end
end
这里我们只是将一个“散列”(它实际上是一个 ActionController::Parameters 实例)直接传递到模型中。恶意用户在这里所要做的就是请求:
POST /users?users[admin]=1
并且他们已经创建了一个管理员帐户。 In 2012 Egor Homakov famously exploited one such loophole in Github 提交到 Rails 存储库。
使用 cURL 或使用网络检查器操纵表单可以轻松执行此类攻击。
如果我们将用户应该能够传递的属性列入白名单:
class UserController < ApplicationController
def create
@user = User.new(
params.require(:user)
.permit(:email, :password, :password_confirmation)
)
if @user.save
redirect_to @user
else
render :new
end
end
end
然后这就避免了漏洞 - 强参数实际上只是一个简单的 DSL,用于对嵌套哈希结构进行切片和切块。 Rail 4 中的变化是,当您将 ActionController::Parameters
的 n 个实例传递给模型时,会引发异常,除非对参数对象 returns true 调用 #permitted?
。这避免了由于程序员的懒惰或无知而导致的批量分配漏洞。
它不会以任何其他方式清理您的输入。例如,如果您不小心对待用户输入,它不会阻止 SQL 注入或远程代码执行。
如果像这个非常人为的示例中那样一个接一个地传递参数,则不需要强参数:
class UserController < ApplicationController
def create
@user = User.new do |u|
u.email = params[:user][:email]
u.password = params[:user][:password]
u.password_confirmation = params[:user][:password_confirmation]
end
if @user.save
redirect_to @user
else
render :new
end
end
end