laminas-api-tools/api-tools-content-validation

Laminas模块,提供输入内容验证功能


README

Build Status

🇷🇺 致俄罗斯公民

我们Laminas的成员来自世界各地。我们中许多人有俄罗斯和乌克兰的朋友、亲戚和同事。我们中的一些人出生在俄罗斯。我们中的一些人现在住在俄罗斯。我们中的一些人的祖父母在二战中与法西斯作战。在这里,没有人支持法西斯主义。

我们中的一个乌克兰亲戚带着儿子从家中逃离。由于前方道路上的轰炸,火车延误了。我们有朋友在防空洞里躲藏。我们在空袭后焦急地关注他们的消息,空袭无差别地袭击医院、学校、幼儿园和住宅。我们不是从任何媒体上得知这些消息的。这是我们亲身体验到的。

您信任我们足够使用我们的程序,我们请求您再次信任我们。我们需要帮助。走出来抗议这场毫无意义的战争。停止杀戮。说“不,战争!”

🇺🇸 致俄罗斯公民

我们Laminas的成员来自世界各地。我们中许多人有俄罗斯和乌克兰的朋友、亲戚和同事。我们中的一些人出生在俄罗斯。我们中的一些人现在住在俄罗斯。我们中的一些人的祖父母在二战中与纳粹作战。在这里,没有人支持法西斯主义。

我们团队的一员有一个乌克兰亲戚,她带着儿子从家中逃离。由于前方道路上的轰炸,火车延误了。我们有朋友在防空洞里躲藏。我们在空袭后焦急地关注他们的消息,空袭无差别地袭击医院、学校、幼儿园和住宅。我们不是从任何媒体上得知这些消息的。这是我们亲身体验到的。

您信任我们足够使用我们的软件。我们要求您信任我们说出真相。我们需要您的帮助。走出来抗议这场不必要的战争。停止杀戮。说“停止战争!”

介绍

Laminas模块,用于自动化输入验证。

允许以下操作

  • 定义命名输入过滤器。
  • 将命名输入过滤器映射到命名控制器服务。
  • 在无效输入上返回带有验证错误信息的ApiProblemResponse

要求

请参阅composer.json文件。

安装

运行以下composer命令

$ composer require laminas-api-tools/api-tools-content-validation

或者,手动将以下内容添加到您的composer.json文件中的require部分

"require": {
    "laminas-api-tools/api-tools-content-validation": "^1.4"
}

然后运行composer update以确保模块已安装。

最后,将模块名称添加到项目的config/application.config.php文件下的modules键下

return [
    /* ... */
    'modules' => [
        /* ... */
        'Laminas\ApiTools\ContentValidation',
    ],
    /* ... */
];

配置

用户配置

此模块利用两个用户级别配置键api-tools-content-validationinput_filter_specs(命名方式是为了将来将此功能移入Laminas)。

服务名称键

api-tools-content-validation键是一个映射,它将控制器服务名称作为键,将值映射为确定对哪些HTTP方法做出响应以及将哪些输入过滤器映射给给定请求的数组。映射的键可以是接受请求体的HTTP方法(即POSTPUTPATCHDELETE),或者可以是单词input_filter。分配给input_filter键的值将在当前HTTP请求方法没有配置输入过滤器的情况下使用。

存在默认过滤器和POST过滤器的示例

'api-tools-content-validation' => [
    'Application\Controller\HelloWorld' => [
        'input_filter' => 'Application\Controller\HelloWorld\Validator',
        'POST' => 'Application\Controller\HelloWorld\CreationValidator',
    ],
],

在上面的示例中,对于PATCHPUTDELETE请求,将选择Application\Controller\HelloWorld\Validator服务,而对于POST请求,将选择Application\Controller\HelloWorld\CreationValidator

从版本1.1.0开始,可以定义两个额外的键来影响应用程序验证行为

  • use_raw_data:如果不存在,则始终将原始数据注入到“BodyParams”容器中(由api-tools-content-negotiation定义)。如果存在此键,并且其值为布尔值false,则将使用输入过滤器验证并过滤的数据。

  • allows_only_fields_in_filter:如果存在,并且use_raw_data为布尔值false,则此标志的值将定义是否将有效负载中存在的额外字段与过滤后的数据合并。

  • remove_empty_data:是否应该从接收到的数据中删除空数据?

    • 如果没有remove_empty_data标志,则不执行任何操作 - 使用原始数据
    • 如果remove_empty_data标志存在并且为布尔值true,则从当前数据数组中删除空数据
    • 如果键与接收到的数据匹配,则不会删除空数据

验证GET请求

  • 自1.3.0以来。

从1.3.0开始,您可以指定GET作为HTTP方法,将其映射到输入过滤器以验证查询参数。配置方法与上述部分中描述的完全相同。

此功能仅在手动配置API时可用;它不在Admin UI中公开。

验证集合请求

  • 自1.5.0以来。

从1.5.0开始,您可以指定以下任一键:

  • POST_COLLECTION
  • PUT_COLLECTION
  • PATCH_COLLECTION

这些键将专门与给定的HTTP方法一起使用,但仅限于匹配集合端点的请求。

验证DELETE请求

  • 自1.6.0以来。

从1.6.0开始,您可以指定以下键作为输入过滤器:

  • DELETE
  • DELETE_COLLECTION

与键相关联的输入过滤器将用于验证请求体中发送的数据。

input_filter_spec

input_filter_spec用于驱动配置创建输入过滤器。此数组的键将是一个唯一名称,但更常见的是基于它映射到api-tools-content-validation键下的服务名称。值将是输入过滤器配置数组,如Laminas手册关于输入过滤器的部分中所述。

示例

'input_filter_specs' => [
    'Application\Controller\HelloWorldGet' => [
        0 => [
            'name' => 'name',
            'required' => true,
            'filters' => [
                0 => [
                    'name' => 'Laminas\Filter\StringTrim',
                    'options' => [],
                ],
            ],
            'validators' => [],
            'description' => 'Hello to name',
            'allow_empty' => false,
            'continue_if_empty' => false,
        ],
    ],

系统配置

以下配置由模块定义,以便在Laminas应用程序中运行。

namespace Laminas\ApiTools\ContentValidation;

use Laminas\InputFiler\InputFilterAbstractServiceFactory;
use Laminas\ServiceManager\Factory\InvokableFactory;

return [
    'controller_plugins' => [
        'aliases' => [
            'getinputfilter' => InputFilter\InputFilterPlugin::class,
            'getInputfilter' => InputFilter\InputFilterPlugin::class,
            'getInputFilter' => InputFilter\InputFilterPlugin::class,
        ],
        'factories' => [
            InputFilter\InputFilterPlugin::class => InvokableFactory::class,
        ],
    ],
    'input_filters' => [
        'abstract_factories' => [
            InputFilterAbstractServiceFactory::class,
        ],
    ],
    'service_manager' => [
        'factories' => [
            ContentValidationListener::class => ContentValidationListenerFactory::class,
        ],
    ],
    'validators' => [
        'factories' => [
            'Laminas\ApiTools\ContentValidation\Validator\DbRecordExists' => Validator\Db\RecordExistsFactory::class,
            'Laminas\ApiTools\ContentValidation\Validator\DbNoRecordExists' => Validator\Db\NoRecordExistsFactory::class,
        ],
    ],
];

Laminas事件

监听器

Laminas\ApiTools\ContentValidation\ContentValidationListener

此监听器优先级为-650,附加到MvcEvent::EVENT_ROUTE事件。其目的是利用api-tools-content-validation配置来确定当前请求所选控制器服务名称是否有配置输入过滤器。如果有,它将遍历配置文件中的映射,以创建适当的输入过滤器(来自配置或Laminas输入过滤器插件管理器),以便验证传入的数据。该监听器利用api-tools-content-negotiation数据容器中的数据来获取反序列化后的内容体参数。

事件

Laminas\ApiTools\ContentValidation\ContentValidationListener::EVENT_BEFORE_VALIDATE

此事件由上述描述的Laminas\ApiTools\ContentValidation\ContentValidationListener::onRoute()在聚合验证数据和确定输入过滤器之间以及实际验证数据时触发。其目的是允许用户

  • 操作输入过滤器。
  • 修改要验证的数据集(自1.4.0版本起可用)。

例如,您可能想验证通过URI提供并在路由中匹配的标识符。您可以这样做:

$events->listen(ContentValidationListener::EVENT_BEFORE_VALIDATE, function ($e) {
    if ($e->getController() !== MyRestController::class) {
        return;
    }

    $matches = $e->getRouteMatch();
    $data = $e->getParam('Laminas\ApiTools\ContentValidation\ParameterData') ?: [];
    $data['id'] = $matches->getParam('id');
    $e->setParam('Laminas\ApiTools\ContentValidation\ParameterData', $data);
});

Laminas服务

控制器插件

Laminas\ApiTools\ContentValidation\InputFilter\InputFilterPlugin(又称getInputFilter)

此插件对Laminas控制器可用。当调用($this->getInputFilter()$this->plugin('getinputfilter')->__invoke())时,它返回MVC事件参数Laminas\ApiTools\ContentValidation\InputFilter中的内容,对于不是Laminas\InputFilter\InputFilter实现的任何值返回null。

服务

Laminas\InputFilter\InputFilterAbstractServiceFactory

此抽象工厂负责根据名称和顶级键input_filter_specs的配置创建并返回适当的输入过滤器。它已注册到Laminas\InputFilter\InputFilterPluginManager