我如何学习验证用户输入是否正确?
我不确定这里的术语,所以让我具体说明一下,当我说“验证”用户输入时,我的意思是提防声称 2021 年 2 月 30 日为生日的用户,而不是防范注入攻击。
是否有正确执行此操作的指南,或者列出了人们常见的错误操作方式?在输入之前确保输入正确的策略(例如,从日历中选择而不是在文本字段中输入)?
请注意,我对特定于语言的答案(例如 ASP.NET 验证控件)不感兴趣,而是对一般策略和原则感兴趣。
I'm not sure of the terminology here, so let me specify that when I say "verify" user input, I mean watch out for users claiming 30 Feb 2021 as their birthdays, rather than guarding against injection attacks.
Are there any guides to doing this correctly, or lists of common ways people do it wrong? Strategies for ensuring correct input even before it's entered (e.g., picking out of a calendar instead of typing into a text field)?
Note that I am not interested in language-specific answers (e.g., ASP.NET Validation Controls) but rather general strategies and principles.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
输入字段越自由,您需要检查的内容就越多。某些语言可能使您可以轻松验证文本字段是否为有效日期;其他人可能不会。
不过,有些用户会讨厌点击日历控件或三个下拉菜单来输入他们的生日。他们可能更喜欢直接输入。这是一种权衡。
The freer you make the input field, the more you have to check. Some languages may make it easy for you to verify that a text field is a valid date; others may not.
Then again, some users will resent clicking on a calendar control or three drop-downs to enter their birthdate. They may prefer to just type it in. That's a trade-off.
您正在寻找的术语是输入验证。
正如您所指出的,如果您使用无法输入无效数据的控件,您可以帮助客户端,但您仍然需要在服务器上实施适当的验证。
为什么不两者都做呢?您想要让自己遭受注入攻击有什么具体原因吗?
假设用户向服务器发送一个字符串,要么是他们自己输入的字符串,要么是由您放置在页面上的控件发送的字符串。第一部分是找到用于将字符串解析为类型化数据的库函数。在您的示例中,您可以使用
DateTime.TryParse
将字符串解析为日期。对于给定的示例,这将失败,因为给定的日期无效。如果您找不到要解析的库函数,您可以尝试自己编写一个解析器。对于简单的验证,您可以将其表达为正则表达式。对于更复杂的输入,您可能需要编写一些执行验证的代码,如果输入语言特别复杂,甚至可能使用解析器库来帮助您。第二部分是实施特定于您的需求的业务验证规则。例如,您知道出生日期必须是过去的日期,但不能太远。这需要一些判断,因为使用您网站的人并非不可能有 100 岁,但他们不太可能有 200 岁,因为据信没有人这么老。
The term you are looking for is input validation.
As you point out if you use a control where it is impossible to enter invalid data you can help the client, but you still need to implement proper validation on the server.
Why not do both? Is there a specific reason why you want to leave yourself open to injection attacks?
Assume that the user sends a string to the server, either one they entered themselves or else one that was sent by a control you placed on the page. The first part is to find a library function for parsing the string into typed data. In your example you could use
DateTime.TryParse
to parse a string to a date. This will fail for your given example as the given date is invalid. If you cannot find a library function for what you are trying to parse you can try to write a parser yourself. For simple validations you may be able to express it as a regular expression. For more complicated inputs you may need to write some code that performs the validation, perhaps even using a parser library to help you if the input language is particularly complicated.The second part is to implement business validation rules specific for your needs. For example you know that a birth date must be in the past, but not too far in the past. This will require some judgement as it's not impossible that someone using your site could be 100 years old, but it's highly unlikely that they are 200 years old since no-one is believed to be this old.
我建议使用一种称为“策略”的设计模式。这是“四人帮”(简称“gof”)创造的模式之一。您可能听说过此模式的一些副本和变体,例如“控制反转”和“依赖注入”。
无论如何,对于面向对象的语言,您要做的就是创建一个名为“validator”的类,它用名为“validate”的方法验证数据。您必须使 validate 接受某种相关形式的输入,或者对其进行重载,以便对不同类型的数据具有不同的方法。或者,如果您可以访问某种形式的泛型,则可以使用它。
接下来,此类的构造函数应采用“validatorstrategy”对象作为参数。然后实际的验证将通过策略对象传递。
为了更进一步,您可以创建某种输入表单生成器系统,在其中使用您自己的类型名称指定输入字段。然后,这些将根据您的前端语言(html/android xml/java swing)生成不同的输入字段,并且它们还将影响验证输入的方式。
嗯..我想知道如何解决两个密码输入字段需要具有完全相同的内容来验证的问题。这在表单生成系统中看起来如何?也许会有一种名为“password”的输入类型,它会生成一个不显示输入且没有验证的输入字段,而另一种名为“passwordsetter”的类型会生成两个不显示输入的输入字段,并具有比较两个字段的数据的验证策略。尽管 D:创建该验证策略可能非常棘手:
i would recommend using a design pattern called "strategy". this is one of the patterns created by "the gang of four", or "gof" for short. there are some copies and variants of this pattern that you may have heard of, e.g. "inversion of control" and "dependency injection".
anyways, for an object oriented language, what you do is that you create a class called "validator", which validates data in a method called "validate". you'll have to make validate accept some relevant form of input, or overload it to have different methods for different sorts of data. or if you have access to some form of generics, you can use that.
next up, the constructor of this class should take a "validatorstrategy" object as argument. and then the actual validation will be passed through the strategy object.
to take this even further, you could then create some sort of input form generator system, where you specify input fields with your own type names. these will then generate different input fields depending on your front end language (html/android xml/java swing), and they will also affect the way in which the input is validated.
hmm.. i wonder how to solve the issue with two password input fields that need to have the exact same content to validate. how would this look in the form generating system? maybe there would be one input type named "password" which would generate one input field which doesn't show the input and has no validation, and another type named "passwordsetter" which would generate two input fields which doesn't show the input, and has the validation strategy of comparing the data from th two fields. creating that validation strategy could be pretty tricky though D: