我有一个拥有客户的用户,而且客户有费用。我有一个创建新费用的表单,在该表单上,用户需要选择费用的客户端。我是这样做的:
= 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魔法?
答案 0 :(得分:0)
你是对的,这是一个安全问题。如果您需要限制对相关记录的访问,您应该始终从服务器端的受限集中进行选择 - 不要相信客户端尊重您的意愿。我会从client_id
中删除attr_accessible
并仅允许手动分配。
处理此问题的最佳方法是创建一个处理费用管理的新类,但如果您正在寻找快速修复,则可以使用控制器操作(但请注意:我不会离开此在长期控制器中。)
从params中提取客户端ID,使用它从当前用户的客户端获取记录,并手动将其分配给费用:
client_id = params[:expense].delete(:client_id)
@expense = current_user.expenses.new(params[:expense])
@expense.client = current_user.clients.find(client_id)