Zendframework 3 - 覆盖 CSRF 验证器
Zendframework 3 - Overwrite CSRF Validator
我尝试从 ZF2 迁移到 ZF3,但许多 viewHelpers 和 验证器不工作。但是只有覆盖 ZendFrameworks 的 viewhelpers / 验证器不起作用...
我要f.e。覆盖 CSRF 验证器以默认允许更高的超时。
我有以下应用程序配置:
$config = array(
// This should be an array of module namespaces used in the application.
'modules' => array(
'Zend\Cache',
'Zend\Db',
'Zend\Log',
'Zend\Mail',
'Zend\Mvc\Console',
'Zend\Mvc\I18n',
'Zend\I18n',
'Zend\Mvc\Plugin\FilePrg',
'Zend\Form',
'Zend\Hydrator',
'Zend\InputFilter',
'zend\Form',
'Zend\Filter',
'Zend\Mvc\Plugin\FlashMessenger',
'Zend\Mvc\Plugin\Identity',
'Zend\Mvc\Plugin\Prg',
'Zend\Navigation',
'Zend\Paginator',
'Zend\Serializer',
'Zend\ServiceManager\Di',
'Zend\Session',
'Zend\Router',
'Zend\Validator',
'DoctrineModule',
'DoctrineORMModule',
'TwbBundle',
'AssetManager',
#'Reliv\ElFinder',
'ZfcUser', //https://github.com/ZF-Commons/ZfcUser
'ZfcUserDoctrineORM',
'BjyAuthorize', // https://github.com/bjyoungblood/BjyAuthorize
'Base',
'Product',
'Blog',
'Admin'
),
// These are various options for the listeners attached to the ModuleManager
'module_listener_options' => array(
// This should be an array of paths in which modules reside.
// If a string key is provided, the listener will consider that a module
// namespace, the value of that key the specific path to that module's
// Module class.
'module_paths' => array(
'./module',
'./vendor',
),
// An array of paths from which to glob configuration files after
// modules are loaded. These effectively override configuration
// provided by modules themselves. Paths may use GLOB_BRACE notation.
'config_glob_paths' => array(
'config/autoload/{,*.}{global,local}.php',
),
// Whether or not to enable a configuration cache.
// If enabled, the merged configuration will be cached and used in
// subsequent requests.
// 'config_cache_enabled' => true,
// The key used to create the configuration cache file name.
//'config_cache_key' => $stringKey,
// Whether or not to enable a module class map cache.
// If enabled, creates a module class map cache which will be used
// by in future requests, to reduce the autoloading process.
// 'module_map_cache_enabled' => true,
// The key used to create the class map cache file name.
#'module_map_cache_key' => $stringKey,
// The path in which to cache merged configuration.
'cache_dir' => "data/cache/",
// Whether or not to enable modules dependency checking.
// Enabled by default, prevents usage of modules that depend on other modules
// that weren't loaded.
// 'check_dependencies' => true,
),
// Used to create an own service manager. May contain one or more child arrays.
//'service_listener_options' => array(
// array(
// 'service_manager' => $stringServiceManagerName,
// 'config_key' => $stringConfigKey,
// 'interface' => $stringOptionalInterface,
// 'method' => $stringRequiredMethodName,
// ),
// )
// Initial configuration with which to seed the ServiceManager.
// Should be compatible with Zend\ServiceManager\Config.
// 'service_manager' => array(),
);
基本模块的模块配置:
namespace Base;
...
return [
...
'validators' => array(
'invokables' => [
\Zend\Validator\Csrf::class => Validator\Csrf::class
]
)
...
]
Base\Validator\Csrf:
<?php
namespace Base\Validator;
class Csrf extends \Zend\Validator\Csrf
{
protected $timeout = 1;
public function __construct($options = [])
{
parent::__construct($options);
die("THIS DOES NOT GETTING PRINTED! NOR DOES THE BREAKPOINT HIT.");
}
}
编辑:添加了自动加载配置
composer.json:
"autoload": {
"psr-4": {
"Base\": "module/Base/src/"
}
}
编辑 2:\Zend\Form\Element\Csrf 的实施可能存在错误?
有趣的是,CsrfValidator 只是在这里直接实例化...
/**
* Get CSRF validator
*
* @return CsrfValidator
*/
public function getCsrfValidator()
{
if (null === $this->csrfValidator) {
$csrfOptions = $this->getCsrfValidatorOptions();
$csrfOptions = array_merge($csrfOptions, ['name' => $this->getName()]);
$this->setCsrfValidator(new CsrfValidator($csrfOptions));
}
return $this->csrfValidator;
}
Stacktrace(\Zend\Validator\Csrf __construct() 中的断点)
StaticPage
是我的另一个模块。
我还用 xdebug 调试并在 CsrfFactory(return 语句)中设置了一个断点以查看它是否被使用(但它没有)。
我以为我可以在 ZF3 中轻松覆盖服务/验证器等...我错过了什么吗?
您可以使用委托器更改元素实例化时附加到表单元素的验证器。本质上,委托者允许您(在这种情况下)在构建表单元素后对其进行修改 - 这个想法解释得很好 here.
在您的情况下,您将创建一个 class:
<?php
namespace Base\Delegator;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\ServiceManager\DelegatorFactoryInterface;
use Zend\Validator\Csrf as CsrfValidator;
class CsrfDelegatorFactory implements DelegatorFactoryInterface
{
public function createDelegatorWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName, $callback)
{
// construct the Csrf form element
$element = call_user_func($callback);
// set the validator with chosen timeout and other options
$element->setCsrfValidator(new CsrfValidator(
[
// ...
'timeout' => 10000
]
));
return $element;
}
}
然后在您的应用程序中将委托人映射到 Zend\Form\Element\Csrf
module.config.php:
'form_elements' => [
// ...
'delegators' => [
\Zend\Form\Element\Csrf::class => [
0 => \Base\Delegator\CsrfDelegatorFactory::class
],
]
],
请注意,这只是将默认分配的验证器更改为Zend\Form\Element\Csrf
,通过其他方式获得的csrf验证器不会受到影响。
我尝试从 ZF2 迁移到 ZF3,但许多 viewHelpers 和 验证器不工作。但是只有覆盖 ZendFrameworks 的 viewhelpers / 验证器不起作用...
我要f.e。覆盖 CSRF 验证器以默认允许更高的超时。
我有以下应用程序配置:
$config = array(
// This should be an array of module namespaces used in the application.
'modules' => array(
'Zend\Cache',
'Zend\Db',
'Zend\Log',
'Zend\Mail',
'Zend\Mvc\Console',
'Zend\Mvc\I18n',
'Zend\I18n',
'Zend\Mvc\Plugin\FilePrg',
'Zend\Form',
'Zend\Hydrator',
'Zend\InputFilter',
'zend\Form',
'Zend\Filter',
'Zend\Mvc\Plugin\FlashMessenger',
'Zend\Mvc\Plugin\Identity',
'Zend\Mvc\Plugin\Prg',
'Zend\Navigation',
'Zend\Paginator',
'Zend\Serializer',
'Zend\ServiceManager\Di',
'Zend\Session',
'Zend\Router',
'Zend\Validator',
'DoctrineModule',
'DoctrineORMModule',
'TwbBundle',
'AssetManager',
#'Reliv\ElFinder',
'ZfcUser', //https://github.com/ZF-Commons/ZfcUser
'ZfcUserDoctrineORM',
'BjyAuthorize', // https://github.com/bjyoungblood/BjyAuthorize
'Base',
'Product',
'Blog',
'Admin'
),
// These are various options for the listeners attached to the ModuleManager
'module_listener_options' => array(
// This should be an array of paths in which modules reside.
// If a string key is provided, the listener will consider that a module
// namespace, the value of that key the specific path to that module's
// Module class.
'module_paths' => array(
'./module',
'./vendor',
),
// An array of paths from which to glob configuration files after
// modules are loaded. These effectively override configuration
// provided by modules themselves. Paths may use GLOB_BRACE notation.
'config_glob_paths' => array(
'config/autoload/{,*.}{global,local}.php',
),
// Whether or not to enable a configuration cache.
// If enabled, the merged configuration will be cached and used in
// subsequent requests.
// 'config_cache_enabled' => true,
// The key used to create the configuration cache file name.
//'config_cache_key' => $stringKey,
// Whether or not to enable a module class map cache.
// If enabled, creates a module class map cache which will be used
// by in future requests, to reduce the autoloading process.
// 'module_map_cache_enabled' => true,
// The key used to create the class map cache file name.
#'module_map_cache_key' => $stringKey,
// The path in which to cache merged configuration.
'cache_dir' => "data/cache/",
// Whether or not to enable modules dependency checking.
// Enabled by default, prevents usage of modules that depend on other modules
// that weren't loaded.
// 'check_dependencies' => true,
),
// Used to create an own service manager. May contain one or more child arrays.
//'service_listener_options' => array(
// array(
// 'service_manager' => $stringServiceManagerName,
// 'config_key' => $stringConfigKey,
// 'interface' => $stringOptionalInterface,
// 'method' => $stringRequiredMethodName,
// ),
// )
// Initial configuration with which to seed the ServiceManager.
// Should be compatible with Zend\ServiceManager\Config.
// 'service_manager' => array(),
);
基本模块的模块配置:
namespace Base;
...
return [
...
'validators' => array(
'invokables' => [
\Zend\Validator\Csrf::class => Validator\Csrf::class
]
)
...
]
Base\Validator\Csrf:
<?php
namespace Base\Validator;
class Csrf extends \Zend\Validator\Csrf
{
protected $timeout = 1;
public function __construct($options = [])
{
parent::__construct($options);
die("THIS DOES NOT GETTING PRINTED! NOR DOES THE BREAKPOINT HIT.");
}
}
编辑:添加了自动加载配置
composer.json:
"autoload": {
"psr-4": {
"Base\": "module/Base/src/"
}
}
编辑 2:\Zend\Form\Element\Csrf 的实施可能存在错误?
有趣的是,CsrfValidator 只是在这里直接实例化...
/**
* Get CSRF validator
*
* @return CsrfValidator
*/
public function getCsrfValidator()
{
if (null === $this->csrfValidator) {
$csrfOptions = $this->getCsrfValidatorOptions();
$csrfOptions = array_merge($csrfOptions, ['name' => $this->getName()]);
$this->setCsrfValidator(new CsrfValidator($csrfOptions));
}
return $this->csrfValidator;
}
Stacktrace(\Zend\Validator\Csrf __construct() 中的断点)
StaticPage
是我的另一个模块。
我还用 xdebug 调试并在 CsrfFactory(return 语句)中设置了一个断点以查看它是否被使用(但它没有)。 我以为我可以在 ZF3 中轻松覆盖服务/验证器等...我错过了什么吗?
您可以使用委托器更改元素实例化时附加到表单元素的验证器。本质上,委托者允许您(在这种情况下)在构建表单元素后对其进行修改 - 这个想法解释得很好 here.
在您的情况下,您将创建一个 class:
<?php
namespace Base\Delegator;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\ServiceManager\DelegatorFactoryInterface;
use Zend\Validator\Csrf as CsrfValidator;
class CsrfDelegatorFactory implements DelegatorFactoryInterface
{
public function createDelegatorWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName, $callback)
{
// construct the Csrf form element
$element = call_user_func($callback);
// set the validator with chosen timeout and other options
$element->setCsrfValidator(new CsrfValidator(
[
// ...
'timeout' => 10000
]
));
return $element;
}
}
然后在您的应用程序中将委托人映射到 Zend\Form\Element\Csrf
module.config.php:
'form_elements' => [
// ...
'delegators' => [
\Zend\Form\Element\Csrf::class => [
0 => \Base\Delegator\CsrfDelegatorFactory::class
],
]
],
请注意,这只是将默认分配的验证器更改为Zend\Form\Element\Csrf
,通过其他方式获得的csrf验证器不会受到影响。