Laravel 5 模型验证和授权

Laravel 5 model validation and authorization

我在如何在我的 laravel 项目中实施验证方面面临两难境地,让我解释一下情况。

  1. 我正在使用 angular JS 前端用户界面并使用 restful resource controllers 与 laravel 通信。
  2. 我在控制器的 store()update() 方法中使用 form request validation 通过 rules() 方法验证数据并使用 authorize() 确定授权方法,它确保我的数据是正确的,并且只有具有正确权限级别的用户才能 add/edit 数据。此时一切都运行良好,只要数据来自 form/ajax 对 api.
  3. 的请求

现在,问题来了。有时 insert/edit 操作需要以编程方式完成,例如每当在 table A 中创建一行时,需要在 table B 中创建一行,但在这样做之前,它还应该 运行 相同的验证规则和检查授权do if table B 是使用表单请求创建的,但是如果我只是调用 say TableA::Create([]) 该行将在没有任何验证的情况下创建。

当然,我也可以在模型内部使用 Validator::make(),但是, a) 它使模型混乱 b) 是代码的重复

所以,我的 objective 是为了确保无论 Table A 的记录如何进入数据库,如果是从应用程序完成的,在保存数据之前都会执行检查,同时保持验证和授权规则的中心。在我看来,要走的路是挂钩模型的 "saving" 事件并以某种方式触发 formrequest 验证器?但我不确定。

我看到了 Jeffrey Way 的 automatic model validator,但那是给 Laravel 4 的。在 Laravel 5.x 中有什么优雅的方法可以做到这一点吗?

另外,作为一个附加问题,当我在其他地方问过这个问题时,一些人说他们是 "not a fan of model based validation",但没有解释为什么这对他们来说不是一个好主意,所以我也会想知道基于模型的验证有哪些缺点?

我建议退后一步。有一种尝试抽象所有内容的诱惑,因此不会重复任何一行逻辑,但您需要了解 why/what 您正在此处验证。

在开发应用程序的早期阶段,您可能会觉得自己在到处重复验证逻辑,并且可能担心如果将验证放入其中会遗漏一些东西控制器 - 例如,"what happens if I add a controller method and fail to validate the data before updating the model?"。因此,接下来的自然步骤是将验证推入模型。

但是!您应该回过头来思考您要验证的内容。您在控制器中验证的内容 并不总是与您在模型中验证的内容相同

有关 MVC 验证的详细信息,请参阅 Stacks 姊妹站点上的以下 link: https://softwareengineering.stackexchange.com/questions/97880/in-mvc-should-a-model-handle-validation

在我看来,陷阱在于在开发的早期阶段,控制器和模型验证 sooooo 非常相似,您可能认为它们是一回事。发生这种情况是因为您自然而然地从一些简单的模型开始着手。您刚刚(在控制器中)验证了用户的名字不是“_-_kablamo!-_-”,然后在模型中您正在做同样的事情。

当您超越简单的用户模型时,您会发现您的模型和控制器更加复杂,并且验证可能不仅仅依赖于当前请求数据 - 例如它可能依赖于其他数据系统,一年中的时间,季节,如果卫星对齐。

我听到你尖叫 好吧,这对你说的第一段没有帮助 "what happens if I miss validation in some new controller method?"。我对此的回答很简单,测试。您的单元测试应该立即接受它。

没有。

这是一个严重的问题,已经进行了过多的讨论而没有足够的解决方案。

Laravel 假定您可以在前端、路由、控制器或模型处进行验证,但代码的体系结构假定大多数用户将在更靠近用户的地方进行验证——要么在路线上,或在控制器上——而不是在模型中。这对于简单的解决方案是可以的。当模型可以被具有不同职责的多个控制器使用时,这是不行的。

模型需要作为规则和验证的单一授权点。
控制器和路由可以应用适合目的的附加验证。

从 40 年的经验来看,您拥有的功能越多,您拥有的开发人员越多,您的数据对可能起诉您的人的财务影响就越大,您的验证将需要越靠近后面进行结尾。您的应用程序越小,开发人员越少,您的信息越不重要,您的信息将在前端附近得到更多的验证。

但是,通常您会在路由、模型、控制器和数据库上针对不同的目的进行验证。 (上面有人说的。)

'testing will catch it' 是千禧一代(贬义的)对这个问题的回答。您的业​​务规则要么是声明式且可观察的,要么不是声明式的且 'magical'。 Jared 时不时地与声明式和可观察式有一点……奇怪的关系。

有多种软件包过去运行良好,但我不确定是否最新。

1. laravel-ardent/ardent

2。 mortimer/poignant

3。 jaspaul/eloquent-model-validation

'simplest' 答案是创建一个基础 class 覆盖保存功能,执行验证,并捕获任何错误,将它们添加到存储桶中。

我个人不知道为什么 'Ardent' 不只是“完成方式”。不幸的是,作者似乎并没有继续下去。