多层应用程序验证输入数据的最佳实践

9
在我们的应用程序中,有各种层次结构。服务层、DAO层和操作(struts应用)。数据从一层传递到另一层。
我们应该在哪里放置输入验证?例如,用户ID、电话号码来自UI界面,它们是强制性的。所以我们已经在客户端进行了验证。按照我的意见,这就是你需要的全部。不需要在其他任何地方进行验证。
但是我的一个同事认为,如果客户直接发送请求,怎么办?所以我们还需要在操作中添加验证。
现在,在DAO中,同一方法在某些其他操作中使用,而那里没有验证,或者说在服务层中,可能会被公开为Web服务,因此也应该有验证。
因此,他建议我们在所有地方都进行验证。但这对我来说没有意义。这是跨层的复制。
这个问题的理想解决方案是什么?例如,验证可能是简单的空值检查或某些复杂的验证。

谢谢大家的回复。我的问题可能涉及到编程层面。(也许我混淆了两个东西)让我详细解释一下。假设有ProcessAction、ProcessService和ProcessDao。它们都有createProcess(Str p1, p2, p3...pn)。现在,假设我在action中进行null检查,以确保所有参数都不为null。那么,在所有3个process中都进行null检查有什么意义呢?(也许这个例子有助于我想问的问题)@Pangea验证框架将工作到Actions层,我该如何在服务层和数据访问层中使用?(如果我漏掉了什么,请纠正我) - Jigar Shah
3个回答

14

同意Pangea的看法,您应该在客户端和服务端终点进行验证。

我想补充一下验证的概念是“快速失败”。您需要在每个层面上添加验证,这样用户或调用者就可以立即得到反馈,知道调用将失败的原因,而不是可能启动事务、进行复杂查询并进行写操作,最后发现某个字段太短。

在客户端,您希望尽可能多地进行验证,以便不浪费用户的时间、带宽和服务器资源(在许多情况下存在争用)。但是,通常无法在客户端上进行所有验证(例如,在注册时检查是否已经使用了此用户名),因此,当您到达服务层时,希望进行检查并返回适当的错误消息。

在服务层,您希望假定所有输入都是潜在的危险和不正确的(它们通常会是这样)。实际上,我认为在服务层上对验证输入更加全面和积极是更好的选择,因为那是您的最后一道防线。如果您在客户端遗漏了一个或两个验证,那么您只需要一个良好的错误处理机制来让用户知道出了什么问题。如果您在服务端错过了某些内容,并发生灾难,那可能意味着数小时或数天的调试和尝试恢复数据库备份。

在数据库层面上还有一些检查,例如强制执行引用完整性等。我通常会尽可能地在尝试写入之前对它们进行检查,因为解释各种关系型数据库管理系统的错误消息并尝试将其转换回用户可理解的语言通常很困难甚至是不可能的。


5
如果您的应用程序提供多个入口点(UI或系统对系统接口或批处理系统),那么您应该在所有这些边缘以及到达服务层之前进行数据清理(空值检查、格式检查、必需性等)。但这并不意味着您需要复制验证逻辑。您可以使用允许您集中验证的框架。在此帖子中可以找到一些示例验证框架。
然而,有些业务验证应该属于您的领域层,并且它们应该保留在您的领域服务层或领域对象中。
我不同意您应该在DAO中执行验证。DAO只应负责CRUD操作。如果它们做得更多,那么您就会有泄漏的层。如果您必须批量处理,则应确保批量通过服务层传递,以便您的批量也通过相同的验证。

1
我能为这个话题增加的一条智慧是,永远不要相信客户端。无论你的客户端是HTML、Flash/Flex还是其他什么,都有可能会被黑客攻击并尝试做一些你不想让他们做的事情。接下来的问题是,如果有可能会被黑客攻击,作为软件工程师,我们必须假设它会被攻击,因此,虽然前端检查很好,并且可以提高应用程序的可用性,但你必须在后端验证所有输入,即使这会导致重复检查。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接