【问题标题】:Strong Parameters and Find in Rails 4Rails 4 中的强参数和查找
【发布时间】:2015-11-19 19:34:07
【问题描述】:

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

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

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

我的confirmpayment控制器如下:

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,因为这不是新订单。我正在使用参数来找到正确的顺序并确认它。这安全吗?还是我错过了什么?

【问题讨论】:

  • payment_id 只是外部提供者的 ID 还是指向数据库中记录的外键。例如。到Payments 表?
  • 就是这样。指向数据库中记录的外键。

标签: ruby-on-rails ruby-on-rails-4 activerecord strong-parameters


【解决方案1】:

所以要澄清一些事情。

强参数负责传递给数据库的允许参数。它应该防止用户修改数据库中不允许修改的属性。

例如:

您有下表的列:

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

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

在您上面的示例中,强参数没有任何优势。您将值直接分配给适当的表列。不能为用户修改数据库中的任何其他属性。如果您的控制器中没有任何其他方法,您可以删除整个 #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。他们更详细地描述了一切。

我希望这会有所帮助!

编码愉快:)

【讨论】:

  • 终于搞定了!当直接对数据库执行@order.update_attributes(params[:order]) 之类的操作时,可以使用如此强大的参数来防止大规模分配。即使这可能是 Rails 的方式,我也不会觉得这样做很舒服。我更喜欢像示例中那样直接分配参数。
【解决方案2】:

关于参数的使用方式,我觉得没什么不对。但是关于安全问题,您可能需要考虑这样一种情况,即用户可以通过将order 参数更改为不属于他的内容来更改任何Order 信息。

在这种情况下,你会希望将查询限制为Order,让他只能确认属于他的订单。

【讨论】:

  • 是的。我在这一行通过 cancan 进行授权:authorize! :confirm, :confirmpayment 只有订单的所有者或管理员才能确认。
【解决方案3】:

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

我有一些建议:

  1. 英文最好编码:operacion to operation
  2. 格子样式 在你的代码ConfirmpaymentController 上课 ConfirmPaymentController

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

【讨论】:

  • 感谢您对样式的建议。然而问题仍然存在:我将如何在我的自定义控制器中使用强参数?我只看到了新操作或更新操作的示例。
  • 您的问题是“这安全吗?”,这就是我的答案。
  • @Augusto 基本上它与您需要的操作的行为相同,只需要考虑您想要允许的参数。我的回答解释了用途。 这样避免输入参数是不允许的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-07
  • 1970-01-01
  • 2013-07-30
  • 2013-10-14
  • 1970-01-01
相关资源
最近更新 更多