2015-04-27 50 views
3

我正在构建一个传统的MVC应用程序。我有一个/ lib文件夹,它定义了处理数据库操作和处理外部API的函数。在处理用户输入时,我应该在哪里验证数据?我应该在路线控制器中验证它,然后将验证的数据发送到数据库功能?或者我应该不在路由控制器中进行验证,并让/ lib文件夹中的函数执行所有验证?你应该在哪里验证/清理数据?

+0

请注意验证和消毒ar e不同的东西。您尽快验证;你尽可能安全地进行消毒。您可以在注册页面上使用正则表达式验证用户名,但是在用户使用服务器之后将其清理干净,或者某人可以使用控制台发送未经过处理的版本,从而绕过大量安全措施。 –

回答

2

对我来说,最自然的地方是在模型中,因为它包含数据。 GRASP专家原则指出,您应该将责任分配给具有履行信息的对象。

我们可以争辩说,控制器可能拥有验证所需的所有信息(数据),但对于我来说,控制器应该很轻。此外,我认为“所有信息”不仅意味着您必须验证数据,而且知道其格式,这就是模型的关注点。控制器可能知道某个模型需要的数据应该如何,但该模型也可以在该控制器范围之外使用,所以它不应该依赖控制器的验证来正常工作,因为模型(几乎)是您最后的机会检测无效数据(您可以也必须在数据库上执行此操作,但数据在进入数据之前应经过验证和消毒,但通常数据库模式与您在模型中应进行的验证之间存在直接匹配) 。

每次用模型进行CRUD操作时,您可能都需要验证数据,并且您将确保您的数据几乎总是正确的。此外,控制器还可以更改进入该模型的数据,因此即使控制器先前对其进行了验证,也可能产生无效数据。

但是,想一想。控制员可能会更改数据,实际上他们会花费很多时间。在表单和模型的字段之间总是有一个直接的映射是很不寻常的,有时你会得到与任何模型没有关系或者没有关系的输入,所以你应该在模型之外验证它们。例如,考虑“重复密码”字段。它与模型无关!只有“密码”字段应达到它。

其他人会说他们更喜欢anemic models,这在某些情况下可能比丰富的模型更适合,但它们也有一些缺点,而且一般来说最适合最好。

您还应该考虑在客户端(即JS)进行验证,以便您可以快速反馈他正在做什么,而不是将数据发送到要验证的服务器,然后等待响应甚至再次加载整个页面!

这样做的一个好方法是使用正则表达式,因为你将在你使用的不同语言之间有相似的表达式,尽管通常这是不够的。或者更好的是,你可以在任何地方使用JS和Node.js,完全不用担心这个问题。

这可能不是您正在寻找的答案,但不仅仅有一个正确的方法来进行验证,因为它对于每个应用程序都是不同的。大多数情况下,验证应该发生在不同的地方,在应用程序的不同层次上进行相同的验证,并在其他一些层次之间进行不同验证。

大约有StackOverflow上这个话题更多的问题,所以你可以检查他们从其他人有不同的看法:

+0

优秀答案谢谢。 – Jon

1

我见过的最好的方法之一是使用装饰器定义服务和层上的验证。如果发生验证错误,将引发一个自定义异常,其中包含由控制器捕获并处理并发送回客户端的验证错误。

控制器应该很薄,并且处理诸如请求和响应之类的事情,而不是业务逻辑。无论使用什么方法,我建议尽量保持它与控制器的分离。