1

我有一个用户有客户,客户有费用。我有一个创建新费用的表单,用户需要在该表单上选择费用用于哪个客户。我是这样做的:

= form_for(@expense) do |f|
...
   = f.select :client_id, options_from_collection_for_select(@possible_clients, "id", "name"), {:include_blank => true}, :class => "span10"

和控制器:

def create
    @expense = Expense.new(params[:expense])
    @expense.user = current_user
    @expense.date = convert_to_db_date(params[:expense][:date])

    respond_to do |format|
      if @expense.save
        format.html { redirect_to expenses_path }
        format.json { render json: @expense, status: :created, location: @expense }
      else
        format.html { render action: "new" }
        format.json { render json: @expense.errors, status: :unprocessable_entity }
      end
    end
  end

和费用模型:

  belongs_to :client
  belongs_to :user
  belongs_to :invoice

  ## ACCESSIBLE ##
  attr_accessible :amount, :category, :date, :invoice_id, :note, :reimbursed, :user_id, :client_id

和客户端模型:

  belongs_to :user
  has_many :contacts, :dependent => :destroy
  has_many :invoices
  has_many :expenses

所以我只是认为这里有一个很大的安全问题。由于用户可以为与费用相关联的客户提交任何 ID……他们可以分配任何客户,对吧?有没有更好的方法来做到这一点?是否有一些防止安全问题的 Rails 魔法?

4

1 回答 1

0

你是对的,这是一个安全问题。如果您需要限制对关联记录的访问,您应该始终从服务器端的受限集中进行选择——不要相信客户端会尊重您的意愿。我会从中删除client_idattr_accessible并且只允许手动分配它。

处理此问题的最佳方法是创建一个处理费用管理的新类,但如果您正在寻找快速修复,您可以使用控制器操作(但请注意:我不会将其留在控制器中在长期)。

从参数中提取客户 ID,使用它从当前用户的客户中获取记录,然后手动将其分配给费用:

client_id = params[:expense].delete(:client_id)
@expense = current_user.expenses.new(params[:expense])
@expense.client = current_user.clients.find(client_id)
于 2013-04-16T02:56:09.060 回答