JavaScript:客户端验证与服务器端验证


179

进行客户端或服务器端验证哪个更好?

在我们的情况下,我们正在使用

  • jQuery和MVC。
  • 在我们的视图和控制器之间传递的JSON数据。

我所做的许多验证工作都是在用户输入数据时对数据进行验证。例如,我使用该keypress事件来防止文本框中的字母,设置最大字符数,并且该数字在一定范围内。

我想更好的问题是,与客户端相比,进行服务器端验证是否有任何好处?


真棒回答大家。我们拥有的网站受到密码保护,并且用户群较小(<50)。如果他们没有运行JavaScript,我们将发送忍者。但是,如果我们要为每个人设计一个站点,那么我同意双方都进行验证。


2
可以禁用javascript
Enrico Murru,

没有确定的方法来阻止禁用JavaScript的用户。如果用户在启用JS的情况下进入您的页面,然后将其禁用,则您无能为力。(好的,您可以使用JS来实现提交控件,这样它就可以在这种情况下停止工作,但是可以像其他所有事情一样绕开它。)
Stewart

Answers:


347

正如其他人所说,您应该同时做这两项。原因如下:

客户端

您希望首先在客户端验证输入,因为您可以为普通用户提供更好的反馈。例如,如果他们输入了无效的电子邮件地址并移至下一个字段,则可以立即显示错误消息。这样,用户可以提交表单之前更正每个字段。

如果仅在服务器上进行验证,则他们必须提交表单,获取错误消息,然后尝试找出问题所在。

(可以通过让服务器重新呈现表单并填充用户的原始输入来减轻这种痛苦,但是客户端验证仍然更快。)

服务器端

您希望在服务器端进行验证,因为您可以防止恶意用户的攻击该用户可以轻松绕过您的JavaScript并将危险的输入提交给服务器。

信任您的UI是非常危险的。他们不仅会滥用您的UI,而且可能根本没有使用您的UI,甚至根本没有使用浏览器。如果用户手动编辑URL或运行自己的Javascript或使用其他工具调整HTTP请求该怎么办?例如,如果他们curl从一个脚本或从一个脚本发送自定义HTTP请求怎么办?

这不是理论上的;例如,我开发了一个旅行搜索引擎,通过向POST用户发送请求,就好像用户已经填写了每个公司的搜索表一样,然后将其收集并排序,从而将用户的搜索重新提交给许多合作伙伴航空公司,公交公司等。所有这些结果。这些公司的表格JS从未执行过,对于我们来说至关重要的是,它们会在返回的HTML中提供错误消息。当然,API会很好,但这就是我们必须要做的。

从安全的角度来看,不允许这样做不仅是幼稚的,而且是非标准的:应允许客户端以他们希望的任何方式发送HTTP,并且您应该正确响应。这包括验证。

服务器端验证对于兼容性也很重要-并非所有用户(即使他们使用的是浏览器)都将启用JavaScript。

附录-2016年12月

有些验证甚至无法在服务器端应用程序代码中正确完成,而在客户端代码中则完全不可能,因为它们取决于数据库的当前状态。例如,“其他人都没有注册该用户名”,“您正在评论的博客文章仍然存在”,“现有的预订不与您请求的日期重叠”或“您的帐户余额仍然足以支付该笔购买费用” ”。只有数据库才能可靠地验证依赖于相关数据的数据。开发人员经常将其弄糟,但是PostgreSQL提供了一些好的解决方案


30
即使是6年之后,这也应该是公认的答案:P
Jacob McKay 2014年

17
是的,我想等近10年才能确定。
Brad8118

2
@kidmosey“这明显违反了DRY原则”是的,这意味着像我们这样的程序员很痛苦。但是想象一下一个注册表格。如果在客户端代码中重复知识“电子邮件地址必须包含@”,则意味着用户获得了更快的反馈,并且他们中的更多人注册了,从而每年产生10万美元的额外收入,它所支付的额外维护费用远远超过了支付的费用。干是一个很好的原则,但这不是唯一的考虑因素。编码质量的确是通过在成本/收益分析中对用户和组织的服务程度来衡量的。
内森·朗

1
@ArunRaaj是的,您将以这种方式解决大多数问题,但并不是100%可靠。如果两个用户同时填写表格,则可能两个人都被告知这user1是一个可用的用户名。他们提交时,除非重新检查服务器端,否则他们都将获得相同的用户名。甚至在服务器应用程序代码中进行检查也可能遇到相同的问题:出现两个请求,第一个请求检查数据库并被告知OK,第二个请求检查数据库并被告知OK,第一个已保存,第二个已保存作为副本。只有db唯一约束可以保证唯一性。
弥敦道(Nathan Long)

1
@NathanLong对种族条件敏感的数据进行验证并不像这句话听起来那么棘手。正确地做是很痛苦的,但是创建一个保留机制,该机制使用同步资源来请求。因此,如果用户键入“ usernameA”,则服务器上的唯一性检查将不允许同时进行多个调用以检查是否唯一;如果是唯一的,则还保留一个分配给客户端的临时令牌,如果使用相同的会话ID测试了不同的用户名,该令牌也会释放。该令牌应在合理的时间后过期。示例:TicketMaster座位储备。
Elaskanator '18年

79

是的,始终可以完全绕过客户端验证。您需要同时做这两个工作,客户端要提供更好的用户体验,服务器端要确保得到的输入是实际验证的,而不仅仅是客户端验证的验证。



31

与客户端验证相比,执行服务器端验证的好处是可以绕过/操纵客户端验证:

  • 最终用户可能已关闭javascript
  • 甚至不使用您网站的人也可以使用专门设计的自定义应用程序将数据直接发送到您的服务器
  • 页面上的Javascript错误(由多种原因引起)可能会导致部分(而非全部)验证运行

简而言之,始终要验证服务器端,然后将客户端验证视为增加“额外”功能以增强最终用户体验。


18

必须始终在服务器上进行验证。

在客户端上进行验证对用户来说也很不错,但完全不安全。


9

好吧,我仍然有一些回答的余地。

除了Rob和Nathan的回答外,我还要补充说,进行客户端验证很重要。在Web表单上应用验证时,必须遵循以下准则:

客户端

  1. 必须使用客户端验证才能过滤来自您网站上真实用户的真实请求。
  2. 客户端验证应用于减少服务器端处理期间可能发生的错误。
  3. 应该使用客户端验证来最大程度地减少服务器端的往返次数,以便节省带宽和每个用户的请求。

服务器端

  1. 您不应假定在客户端成功完成验证是100%完美的。即使服务的用户少于50个,也是如此。您永远不会知道您的哪个用户/雇员变成了“邪恶”,并且知道自己没有适当的验证,因此会进行一些有害的活动。
  2. 即使在验证电子邮件地址,电话号码或检查某些有效输入方面非常完美,它也可能包含非常有害的数据。无论其正确与否,都需要在服务器端对其进行过滤。
  3. 如果绕过客户端验证,则服务器端验证可以使您免受服务器端处理的任何潜在损害。最近,我们已经听到了许多有关SQL注入的故事以及可能为了获得一些邪恶好处而应用的其他技术的故事。

两种类型的验证在各自的范围内都扮演着重要角色,但最强的是服务器端。如果您在单个时间点收到1万用户,那么您肯定会最终过滤掉进入您的Web服务器的请求数量。如果您发现一个错误,例如电子邮件地址无效,那么他们会再次发回该表格,并请您的用户更正该表格,这肯定会占用您的服务器资源和带宽。因此更好地应用javascript验证。如果禁用了javascript,则您的服务器端验证将可以挽救,我敢打赌,由于99.99%的网站使用javascript并且所有现代浏览器默认已启用javascript,因此只有少数用户会意外禁用它。


我见过人们忽视了完全防止代码注入的行为,没关系只在客户端这样做。在没有链接的情况下,没有对代码注入的完整引用:xkcd.com/327 :)
Stewart

8

您可以进行服务器端验证,然后将每个字段的验证结果发送回JSON对象,将客户端Javascript降至最低(仅显示结果),并且仍然具有用户友好的体验,而不必在客户端和服务器上都重复自己的操作。


3
方便使用的?也许。几乎瞬间黄油般光滑?可能不是。
2015年

4

客户端应通过HTML5输入类型模式属性使用基本验证,因为它们仅用于渐进式增强以提供更好的用户体验(即使<IE9和safari不支持它们,但我们也不依赖它们)。但是主要的验证应该在服务器端进行。


“但是主要的验证应该在服务器端进行。” 不应该,必须。
斯图尔特


2

可以在运行时修改JavaScript。

我建议一种在服务器上创建验证结构并将其与客户端共享的模式。

您将需要在两端分别使用验证逻辑,例如:

"required"inputs客户端的属性

field.length > 0 服务器端。

但是,使用相同的验证规范将消除两端镜像验证的某些冗余(和错误)。


2

客户端数据验证对于改善用户体验很有用:例如,我输入错误电子邮件地址的用户不应该等待,直到远程服务器处理了他的请求以了解他的错字。

但是,由于攻击者可以绕过客户端验证(甚至可能根本不使用浏览器),因此服务器端验证是必需的,并且必须是保护后端免受恶意用户攻击的真正大门。


1

我遇到了一个有趣的链接,该链接将严重错误,系统错误和随机错误区分开来

Client-Side validation非常适合防止严重和随机错误。通常,纹理和输入的最大长度。不要模仿服务器端验证规则;提供您自己的总的经验法则验证规则(例如,在客户端上为200个字符;n在服务器端由强大的业务规则决定)。

Server-side validation非常适合防止系统错误;它将执行业务规则。

在我参与的一个项目中,验证是通过ajax请求在服务器上完成的。在客户端上,我相应地显示错误消息。

进一步阅读:严重,系统,随机错误:

https://answers.yahoo.com/question/index?qid=20080918203131AAEt6GO


-2

如果您要进行光验证,则最好在客户端上进行。它将节省网络流量,这将帮助您的服务器更好地运行。如果复杂的验证涉及从数据库或诸如密码之类的数据中提取数据,那么最好在可以安全检查数据的服务器上进行验证。


2
您最喜欢的不是什么好主意。用户始终可以绕过客户端验证,然后将所需的任何内容提交给数据库。
kremuwa
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.