- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我们正在构建一个需要精确度的 api 端点。我们希望对 POST/PUT 到服务器的参数强制执行严格验证。
如果 api 用户发送了一个不受支持的 key=value
对(例如,我们允许参数 [first_name, last_name] 而用户包含一个不受支持的参数 [country]),我们想要验证失败。
已尝试构建一个名为 allowed_attributes
的自定义验证器(用作 allowed_attributes:attr1,attr2,...
),但要使其在 中可用$validationRules
数组,它必须应用于嵌套/子属性列表的父级(...因为否则我们的自定义验证器无法访问正在验证的属性)。
Validator::extend('allowed_attributes', 'App\Validators\AllowedAttributesValidator@validate');
这给其他验证器带来了问题,然后我们不得不预测这个父/子结构和围绕它的代码,包括错误键和错误消息字符串的额外验证后清理。
tl;dr:非常脏,不是干净的实现。
$validationRules = [
'parent' => 'allowed_attributes:first_name,last_name',
'parent.first_name' => 'required|string|max:40',
'parent.last_name' => 'required|string|max:40'
];
$isValid = Validator::make(['parent' => $request], $validationRules);
var_dump("Validation results: " . ($isValid ? "passed" : "failed"));
关于如何在 Laravel 中更干净地完成此操作的任何想法/建议,而不需要使用父/子关系来访问所有 $request 属性的列表(在自定义验证器中)?
最佳答案
我更喜欢发布一个新答案,因为该方法与之前的方法不同,而且更加简洁。所以我宁愿将这两种方法分开,而不是在同一个答案中混合在一起。
自从我上次回答以来,在深入研究验证命名空间的源代码后,我发现最简单的方法是扩展验证器类以实现 passes()
函数来检查你的内容需要。
此实现的好处是还可以毫不费力地正确处理单个数组/对象字段的特定错误消息,并且应该与通常的错误消息翻译完全兼容。
你应该首先在你的应用程序文件夹中创建一个Validator类(我把它放在app/Validation/Validator.php
下)并实现passes 像这样的方法:
<?php
namespace App\Validation;
use Illuminate\Support\Arr;
use Illuminate\Validation\Validator as BaseValidator;
class Validator extends BaseValidator
{
/**
* Determine if the data passes the validation rules.
*
* @return bool
*/
public function passes()
{
// Perform the usual rules validation, but at this step ignore the
// return value as we still have to validate the allowance of the fields
// The error messages count will be recalculated later and returned.
parent::passes();
// Compute the difference between the request data as a dot notation
// array and the attributes which have a rule in the current validator instance
$extraAttributes = array_diff_key(
Arr::dot($this->data),
$this->rules
);
// We'll spin through each key that hasn't been stripped in the
// previous filtering. Most likely the fields will be top level
// forbidden values or array/object values, as they get mapped with
// indexes other than asterisks (the key will differ from the rule
// and won't match at earlier stage).
// We have to do a deeper check if a rule with that array/object
// structure has been specified.
foreach ($extraAttributes as $attribute => $value) {
if (empty($this->getExplicitKeys($attribute))) {
$this->addFailure($attribute, 'forbidden_attribute', ['value' => $value]);
}
}
return $this->messages->isEmpty();
}
}
这实际上会扩展默认的 Validator 类以在 passes 方法上添加附加检查。该检查通过转换为点表示法(以支持数组/对象验证)的输入属性和分配了至少一个规则的属性之间的键来计算数组差异。
那么您错过的最后一步是在服务提供商的boot方法中绑定(bind)新的Validator类。为此,您只需重写 Illuminate\Validation\Factory
类的解析器,将其作为'validator'
绑定(bind)到 IoC 容器中:
// Do not forget the class import at the top of the file!
use App\Validation\Validator;
// ...
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
$this->app->make('validator')
->resolver(function ($translator, $data, $rules, $messages, $attributes) {
return new Validator($translator, $data, $rules, $messages, $attributes);
});
}
// ...
您无需执行任何特定操作即可使用此功能。只需照常调用 validate
方法即可:
$this->validate(request(), [
'first_name' => 'required|string|max:40',
'last_name' => 'required|string|max:40'
]);
要自定义错误消息,您只需在 lang 文件中添加一个翻译键,键等于 forbidden_attribute
(您可以在 上的自定义验证器类中自定义错误键名称>addFailure
方法调用)。
示例: resources/lang/en/validation.php
<?php
return [
// ...
'forbidden_attribute' => 'The :attribute key is not allowed in the request body.',
// ...
];
注意:此实现仅在 Laravel 5.3 中进行了测试。
关于php - Laravel 验证 : only allow known properties/attributes, 否则验证失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55503686/
016-03-07T09:10:16.992-0600 W NETWORK [HostnameCanonicalizationWorker] Failed to obtain name info f
我有一个工作的 C 程序,其中字符串数组的长度在编译时已知。它是: char array_person_name[3][101]; char person_name[101] = ""; ... st
我正在做一个需要Graph DB 的项目。我正在使用 C# .Net Core 开发项目。我不得不选择 ArangoDB 作为这个项目的 Graph DB。不幸的是,.Net 没有官方驱动程序。这就是
我正在尝试使用 DataContractSerializer 将对象序列化为 Xml。我有以下类(class); [ActiveRecord(Lazy = true)] [KnownType(type
我有: 身份服务器 4, 具有 OpenId Connect 和混合流的 Mvc 应用 WebApi 应用 假设用户已经获得带有 id_token 和访问 token 的 cookie。然后他从 mv
我有: 身份服务器 4, 具有 OpenId Connect 和混合流的 Mvc 应用 WebApi 应用 假设用户已经获得带有 id_token 和访问 token 的 cookie。然后他从 mv
我有一个简单的 Asp.Net Core Azure Web 应用程序,需要向本地 Rest 服务发出 http get 请求。此 Rest 服务托管在 IIS 上,仅针对端口 443 设置了绑定(b
这个问题可能是一个很好回答的问题,但不幸的是我不知道正确的术语来正确地问它,所以...... template class __bit_iterator; 有人可以在这里解释最后一个模板参数吗?我唯
在基于ASP.NET Core 1.1.1开发的VS2017 Ver 15.3.3应用程序中,我使用Account confirmation and password recovery in ASP.
我有一个应用程序(aspnet core app 3.1),在启动期间使用以下代码从 azure blob 存储加载数据: BlobClient client = new BlobClient(loa
我有一个应用程序(aspnet core app 3.1),在启动期间使用以下代码从 azure blob 存储加载数据: BlobClient client = new BlobClient(loa
我想知道如何查询Wikidata通过使用别名(“也称为”)。 现在我正在努力 SELECT ?item WHERE { ?item rdfs:aliases ?alias. FILTER(CONTAI
这是一个 PNG 类,在类文档中列出了两个构造函数,如下所示。 PNG::PNG ( string const & file_name ) Creates a PNG image
这就是我目前拥有的,以及我的教授提供的扫描仪。 #include "Similarity.h" #include "Scanner.h" using namespace std; int Simila
我想从我的 asp 页面连接到 mysql 数据库。因此,根据我的托管服务提供商的说法,我使用了连接字符串,其中服务器被指定为“localhost:3309” Dim myConnection As
我正在尝试集成的第三方应用程序,要求将文件放入 .well-known文件夹。如何使该文件可从 URL 访问? ( example.com/.well-known/token.txt )。站点部署为
尝试学习 Hibernate,我正在尝试学习如何执行 NamedQuries但每次我都会收到 Exception in thread "main" org.hibernate.MappingExcep
我正在尝试将 PWA 发布到 Google Playstore。我被困在数字 Assets 握手中。 这是我的 nginx conf - location /asd/ { default_t
我正在尝试设置 wordpress xml-rpc带 rails : blog = XMLRPC::Client.new("localhost/blog", "/xmlrpc.php", 80) 但是
我在我的 nginx 配置中有这个: location ~ /\. { deny all; } location /.well-known/ { allow all; } 但是我还是不
我是一名优秀的程序员,十分优秀!