Rails 在不使用 hidden_field 标记的情况下向请求传递额外参数

Rails pass extra parameters to a request without using hidden_field tag

我有两个模型,名为 Post 和 PostComment。 目前,我使用 hidden_field 表单助手来发送额外的数据,例如 post 时间、评论的用户 ID poster 和正在发表评论的 post ID像这样:

<%= f.hidden_field :posttime, value: Time.now.getutc %>
<%= f.hidden_field :post_id, value: @post.id %>
<%= f.hidden_field :user_id, value: current_user.id %>

我很晚才意识到我可以使用浏览器的检查器更改这些值,因此这是一个安全漏洞。那么如何安全地发送这些参数呢?

通常这些值不是通过表单传递的,而是通过 URL 使用嵌套的 URL 访问的(在这里阅读如何:http://guides.rubyonrails.org/routing.html

例如,要使用 post_id 形式的 url,您需要将您的评论路径设置为包含 post,例如您将有 new_post_comment_path,并且在您的控制器,您可以访问 params[:post_id] 而无需通过表单传递它。

你的表单会变成这样:

<% form_for [@post, Comment.new] do |f| %>
   ...

回复:user_id - 绝对不要在表单中传递它,你说得对,这是一个很大的安全问题(人们可以为其他人添加评论!)只需通过您的控制器中的身份验证方法(即 current_user)。

你最终会在你的控制器中得到这样的东西,例如:

def create
  @post = Post.find(params[:post_id])
  @comment = @post.comments.new(comment_params)
  @comment.user = current_user
  if @comment.save
    redirect_to [@post, @comment]
  else
    render_action :new
  end
end

private

# Don't forget to use require/permit to make sure the user can't 
# fake up the user/post id fields themselves out of whole-cloth
def comment_params
  # or whatever your permitted comment-fields are.
  params.require(:comment).permit(:content)
end

Time.now.getutccurrent_user.id 已经在您的应用程序中的 createupdate 方法中可用,因此您真的不需要将它们传递回去。至于 @post.id,您可以将其存储在 newedit 方法的会话变量中...

session[post_id] = @post.id

然后在您的 create 或`更新方法中...

@post_comment.post_id = session[:post_id]