[英]Declare that the value in strong params must NOT be an array or of a one scalar type
Application accepts a GET request to index products and accepts page
param (which should be an integer).应用程序接受 GET 请求以索引产品并接受page
参数(应该是整数)。
eg http://localhost/products?page=2
例如http://localhost/products?page=2
Is there a way to ensure that it really is an integer?有没有办法确保它真的是 integer?
Or actually the problem is: Is there a way to ensure that it is NOT an array?或者实际上问题是:有没有办法确保它不是数组?
eg http://localhost/products?page[]=2
or http://localhost/products?page[random_key]=2
例如http://localhost/products?page[]=2
或http://localhost/products?page[random_key]=2
This will result in an error somewhere in the code.这将导致代码某处出错。
Now, I know that there is a way to declare it should be an array or a json:现在,我知道有一种方法可以声明它应该是一个数组或一个 json:
To declare that the value in params must be an array of permitted scalar values, map the key to an empty array:要声明 params 中的值必须是允许标量值的数组,map 是空数组的键:
params.permit(id: [])
And the easiest method I can think of is literally to test if it is NOT an array:我能想到的最简单的方法就是直接测试它是否不是数组:
run_the_code unless params[:page].is_a?(Array)
# or
run_the_code if params[:page].is_a?(Integer)
But isn't there a simpler way to use ActionParameters API for example?但是没有更简单的方法来使用 ActionParameters API 吗?
eg例如
params.permit(page: :integer)
The strong parameters API is really only designed to do one thing - slice the parameters down to a whitelist to avoid mass assignment vulnerabilities where a malicous user manages to assign properties they should not have been able to assign.强参数 API 实际上只设计用于做一件事——将参数切分到白名单,以避免恶意用户设法分配他们不应该分配的属性的大规模分配漏洞。 It's not concerned with validating the presence or type of the parameters.它不关心验证参数的存在或类型。 That's not its job.那不是它的工作。
You don't have to worry about it being an array if you just use .permit(:page)
since the permitted scalar types doesn't include hashes or arrays. But this really has more to with preventing exploits where a setter method could accept a hash then validating the type of the parameters.如果您只使用.permit(:page)
,则不必担心它是一个数组,因为允许的标量类型不包括哈希或 arrays。但这实际上更多地用于防止 setter 方法可以接受的漏洞利用a hash 然后验证参数的类型。
There is also the small fact that formdata pairs (both in the query and request body) are not typed - its all just strings and its really just the backend that converts the parameters into its expected types.还有一个小事实,即表单数据对(在查询和请求正文中)都没有类型化——它只是字符串,实际上只是将参数转换为预期类型的后端。 params[:page].is_a?(Integer)
will thus always be false. params[:page].is_a?(Integer)
因此将始终为假。 Beyond parsing out hashes and arrays Rack doesn't actually have any built in type hinting like for example ?page(i)=2
like you'll find in some frameworks.除了解析哈希和 arrays Rack 实际上没有任何内置类型提示,例如?page(i)=2
就像您在某些框架中会发现的那样。
Typically in Rails the model handles typecasting the user input and providing validations.通常在 Rails 中,model 处理用户输入的类型转换并提供验证。
# this is ridiculously overkill
class Paginator
include ActiveModel::Model
include ActiveModel::Attributes
attribute :page, :integer
attribute :per_page, :integer
validates :page, numericality: { only_integer: true }
validates :per_page, numericality: { only_integer: true }
def to_query
attributes.symbolize_keys.compact_blank
end
end
paginator = Paginator.new(params.permit(:page, :per_page))
if paginator.valid?
Othermodel.paginate(**paginator.to_query)
end
However there are gems that provide alternative approaches such as dry-validations or you can just simply write a method which rejects the parameter if it cannot be coerced into a non-zero integer.然而,有些 gem 提供替代方法,例如干式验证,或者您可以简单地编写一个方法,如果不能将参数强制转换为非零值 integer 则拒绝该参数。
private
def page
params.permit(:page).to_i.then{ |n| n.zero? ? nil : n }
end
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.