首页 > 解决方案 > Rails 什么时候应该使用强参数?

问题描述

我不确定我是否正确理解了强参数的概念。我应该对仅用于编辑某些数据的参数使用强参数吗?或者我应该将它们用于我想进入控制器的每个参数?例如我想获取两个日期之间的数据,所以我需要 date1 和 date2 作为参数。我应该在这里使用强参数吗?

标签: ruby-on-railsstrong-parameters

解决方案


了解何时应该使用强参数的最简单方法是了解什么是质量分配自愿性。在 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 

他们已经创建了一个管理员帐户。2012 年,著名的 Egor Homakov 利用 Github中的一个此类漏洞提交到 Rails 存储库。

使用 cURL 或使用 Web 检查器操作表单来执行此类攻击是微不足道的。

如果我们将用户应该能够传递的属性列入白名单:

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给模型时,会引发异常,除非调用#permitted?参数对象返回 true。这避免了仅仅由于程序员的懒惰或无知而发生批量分配漏洞。

它不会以任何其他方式清理您的输入。例如,如果您不小心对待用户输入,它不会阻止 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

推荐阅读