什么可能导致 Rails 将参数构造为扁平而不是分层?

问题描述 投票:0回答:1

我的 Rails 应用程序中有一个奇怪的错误,该错误是由某人可能做了他们不应该做的事情而触发的。但我不知道他们可能在做什么,从而如何防范。

当前设置是 Rails 7.1.3.2Ruby 3.3.1,尽管我已经看到它好几个月了,包括回到 Rails 7.0 和 Ruby 3.2

最终,我收到以下错误:

ActionController::ParameterMissing: param is missing or the value is empty: organization

形式比较简单

<form action="/o" accept-charset="UTF-8" method="post">
    <input type="hidden" name="authenticity_token" value="...">
    <label for="organization_a1">A1</label>
    <input required="required" type="text" name="organization[a1]" id="organization_a1">
    <label for="organization_a2">A2</label>
    <input type="text" name="organization[email_domain]" id="organization_a2">
    <input type="submit" name="commit" value="Continue" data-disable-with="Continue">
</form>
...

控制器中也没有发生任何奇怪的事情。

def create
  @organization = Organization.create(organization_params)
  redirect_to start_home_index_path
end

def organization_params
  params.require(:organization).permit(:a1, :a2, ...)
end

第一个请求通过并重定向得很好,第二个请求在

params.require
调用上失败

如果我查看日志,我会收到以下请求序列。

INFO -- Started POST "/o" for 47.238.233.78 at 2024-05-14 17:37:48 +0000
Processing by OrganizationsController#create as */*
INFO -- Parameters: {"authenticity_token"=>"[FILTERED]", "organization"=>{"a1"=>"v1", "a2"=>"v2"}
, "commit"=>"Continue"}
INFO -- <successful redirect>
...
INFO -- Started POST "/o" for 47.238.233.78 at 2024-05-14 17:37:51 +0000
INFO -- Processing by OrganizationsController#create as */*
INFO -- Parameters: {"authenticity_token"=>"[FILTERED]", "organization[a1]"=>"v1", "organization[a2]"=>"v2", "commit"=>"Continue", "organization"=>{}}
INFO -- Completed 400 Bad Request in 1ms
ERROR -- ActionController::ParameterMissing (param is missing or the value is empty: organization)
...

所以我可以在 Rails 日志中看到指向

{}
的空组织,但是如果我查看错误中的请求正文,它会显示为
..."organization[a1]":"v1","organization[a2]:"v2"..."
没有像
"organization":""

这样奇怪的空作业

您可以在日志中看到,这似乎是某人(同一IP地址)在3秒内提交了两次表单。第一次成功,第二次失败。

我尝试了多种不同的方法来重新创建它,包括在提交之前更改表单中的authenticity_token隐藏字段(奇怪的是,rails没有这方面的问题)。还可以使用curl多次重新提交相同的请求(没问题)。如果我更改会话 cookie 的值,这确实会导致 Rails 出现错误,但会导致不同的错误(无法验证 CSRF 令牌的真实性)。

那么什么会导致 Rails 出现这种情况呢?我当然可以通过多种不同的方式处理这个错误,但我想了解用户如何触发 Rails 以这种方式执行操作。

ruby-on-rails strong-parameters
1个回答
0
投票

您可以只使用简单的表单助手,他们会发送有效的参数

<%= form_with model: Organization.new, url: organizations_path, method: :post do |form| %>
  <%= form.label :a1, 'A1' %>
  <%= form.text_field :a1 %>
  <%= form.label :a2, 'A2' %>
  <%= form.text_field :a2 %>
  <%= form.submit 'Continue' %>
<% end %>
© www.soinside.com 2019 - 2024. All rights reserved.