我刚开始学习Rails并尝试制作我的第一个应用程序。 只是想知道是否可以使用像这样的结构
<%= form_tag create_message_path, :method => :post do %>
<%= text_area_tag "message", nil %>
<%= hidden_field_tag "receiver", @order.printer.user.id %>
<%= hidden_field_tag "order_id", @order.id %>
<%= submit_tag "Submit" %>
<% end %>
基本强大的参数。
class MessagesController < ApplicationController
before_action :correct_user, only: [:update, :destroy]
def create
if current_user
@message = current_user.messages.build(message_params)
if @message.save
flash[:success] = "Сообщение создано"
redirect_to :back
else
redirect_to :back
end
else
redirect_to login_path
end
end
private
def message_params
params.permit(:message, :read, :receiver, :user_id, :printer_id, :order_id )
end
def correct_user
@message = current_user.messages.find_by(id: params[:id])
redirect_to root_url if @message.nil?
end
end
不是一个线程吗?用户可以更改html输入值并发送一些信息(如要发送给其他订单的消息)吗?
编辑1:
@order = Order.find(params[:id])
message_item = {
user_id: current_user.id,
receiver: @order.printer.user.id,
message: params[:message],
order_id: @order.id
}
@message = current_user.messages.build(message_item)
答案 0 :(得分:5)
首先,隐藏的参数可以更改,并且它们不适合任何敏感信息。
其次,从message_params方法中删除这些参数。你不想在params hash中允许它们(不允许你的表单上没有的参数):
git commit -S -m 'message'
此外,您可能希望删除:也读取,因为很可能您会在其他控制器操作中设置它。
第三,你通过分配设置这些参数:
params.permit(:message, :read)
注意,您不需要编写@message = current_user.messages.build(message_params)
@message.receiver = @order.printer.user.id
@message.order_id = @order.id
,因为它将由Rails为您完成。
答案 1 :(得分:4)
你是对的,术语hidden
只描述了没有显示该输入的控件。但是,任何人都可以使用页面检查器将值或POST更改为具有任何所需值的表单的目标URL。您应始终确保通过隐藏字段接收的值在您允许的范围内。
答案 2 :(得分:2)
用户可以绝对更改这些值,并可以发送他们想要的任何数据。您不应该使用隐藏标记来传递任何真正敏感的数据,您应该假设攻击者可以将它们更改为他们想要的任何内容。在实践中,隐藏字段适用于传递一些配置/上下文信息,以及用于暴力攻击/ DoS保护令牌。例如,您可以使用隐藏字段传入一个值,指定这是一个搜索或登录请求,但不适合指定管理员发出请求,或者哪个用户正在发出请求。
答案 3 :(得分:2)
对于像这样的敏感数据,您应该使用服务器端会话变量(最简单)或使用HMAC来验证客户端是否更改了数据。
模板:
<input type=hidden name=foo value=bar>
<input type=hidden name=hmac value=<%=hmac($serverSecret + "foo=bar")%>>
然后在表单提交上,根据$serverSecret
重新计算HMAC,并声明$foo
的声明值,并确保它与声明的$hmac
值相同