强参数并在 Rails 4 中查找

Strong Parameters and Find in Rails 4

我在自定义控制器中遇到强参数问题。我了解如何在新操作或更新操作中使用强参数。但是,我似乎无法弄清楚这是否是在我的自定义操作中对 params[] 哈希的不安全使用。

我的视图重定向到具有订单 ID 和操作编号的控制器:

link_to 'Confirm', confirmpayment_confirm_path(order: order, operacion: order.operacion), :data => { confirm: 'Are you sure?' }

我的确认支付控制器如下:

class ConfirmpaymentController < ApplicationController
  before_action :authenticate_user!

  def lookup
    authorize! :lookup, :confirmpayment
    @orders=Order.where(:status => 'PENDING')
  end

  def confirm
    authorize! :confirm, :confirmpayment
    @order=Order.find(params[:order])
    @order.payment_id = params[:operacion]
    @order.confirm_payment_date = DateTime.now()
    @order.save
  end

  def order_params
    params.require(:order).permit(:order, :operacion) 
  end

end  

问题是:

我在确认操作中没有使用 order_params,因为这不是新订单。我正在使用参数来找到正确的顺序并确认它。这安全吗?还是我遗漏了什么?

强参数:防止意外暴露不该暴露的内容。它们通常在您创建或更新模型时使用,以避免输入不允许的参数。

我有一些建议:

  1. 英文最好编码:operacionoperation
  2. 检查样式 在您的代码中 ConfirmpaymentController 到 class ConfirmPaymentController

你可以看到:best practices and style prescriptions for Ruby on Rails 4 :)

关于参数的使用方式,我觉得没什么问题。但是关于安全问题,你可能想考虑用户可以通过将 order 参数更改为不属于他的东西来更改任何 Order 信息的情况。

那样的话,你会想将查询限制在Order,让他只能确认属于他的订单。

所以要弄清楚一些事情。

Strong Parameters 负责传递到数据库的允许参数。它应该防止用户修改数据库中他们不允许修改的属性。

例如:

您有以下 table 列:

User:
 - firstname
 - lastname
 - email
 - password_digest
 - role (user, admin)

您可能想阻止普通用户更改他们的 role。但是,如果您将参数散列原封不动地传递给数据库,他还可以将带值的 role 键添加到散列中。您的应用程序会接受它。 强参数 检查散列并防止更改。

在您上面的示例中,强参数没有带来任何优势。您将值直接分配给适当的 table 列。无法为用户修改数据库中的任何其他属性。如果您的控制器中没有任何其他方法,您可以删除整个 #order_params。如果您尝试直接传递散列,强参数只会引发异常。

但是我建议您在分配之前在数据库中搜索付款。如果您直接分配 payment_id,则无法保证付款存在。因此,首先检查付款,如果发现它,则将其分配给订单。

这是我的做法:

class PaymentConfirmationController < ApplicationController
  before_action :authenticate_user!
  before_action :authorize_user!   # To DRY up your code

  def lookup
    @orders = Order.where(:status => 'PENDING')
  end

  def confirm
    @order = Order.find(params[:order_id])
    @payment = Payment.find(params[:operation_id])
    # You should catch the exceptions if an order or payment wasn't found

    @order.payment = @payment
    @order.payment_confirmation_date = Time.now()
    @order.save
  end

  private

  def authorize_user!
    authorize! :confirm, :confirmpayment
  end
end

我还没有测试代码,但它应该可以工作。

这是Docs of Strong Parameters。他们更详细地描述了一切。

希望对您有所帮助!

编码愉快:)