brain / nonces
WordPress 处理非ces的面向对象包。
Requires
- php: >=5.5.0
Requires (Dev)
- brain/monkey: ~1.4
- phpunit/phpunit: ~4.8
README
Nonces 是一个面向对象的 WordPress 包,用于处理非ces。
目录
介绍
WordPress 的非ces函数在面向对象环境中并不真正有效。
它们需要传递 "keys" 和 "actions",最终导致代码中硬编码那些字符串在类的代码中,或者将它们存储在全局可访问的位置。
两种解决方案都不是理想的。
这个包旨在提供一个方法来简化在面向对象代码中使用 WordPress 非ces。
要解决的具体问题包括
- 避免处理硬编码的非ces "keys" 和 "actions"
- 能够按非ces定制非ces TTL
- 采用更适合面向对象的方案,具有足够的灵活性,可以扩展为不同的非ces实现
工作原理
重新思考 WordPress 工作流程
WordPress 非ces 工作流程是
- 对于一项 "任务",在请求中放置一个非ces 键和一个非ces 值(作为 URL 查询变量或通过隐藏表单字段)。该 "键" 只是硬编码的,该值由
wp_create_action()
生成,它是一个基于特定于 "任务" 的 "action" 的哈希值; - 请求处理程序从请求数据中提取非ces 值(因此它需要知道非ces "key"),并用
wp_verify_nonce()
验证它,该验证器需要知道 "action"。
我们想要避免的是需要知道在非ces 创建 和 验证的地方的 "keys" 和 "actions",这会导致代码不同部分之间的紧密耦合,以及更实际的问题,即存储这些值的位置,或者简单地硬编码它们。
此包 工作流程是
- 对于一项 "任务",创建一个非ces 对象,将动作字符串传递给构造函数。没有 "key",并且 "action" 不需要在其他任何地方被知道。
- 请求处理程序需要接收(作为方法参数或作为构造函数的依赖项注入)一个非ces 任务实例,并使用该对象验证请求。
因此,使用此包,工作流程将类似于(伪代码)
class TaskForm { public function __construct(\Brain\Nonces\NonceInterface $nonce){ $this->nonce = $nonce; $this->url = admin_url('admin-post.php'); } public function printFrom() { $url = add_query_arg($this->nonce->action(), (string) $this->nonce, $this->url); echo "<form action={$url}>"; // rest of form here... } } class TaskFormHandler { public function __construct(\Brain\Nonces\NonceInterface $nonce){ $this->nonce = $nonce; } public function saveForm() { if (! $this->nonce->validate()) { // handle error here... } // continue processing here... } }
因此,构建表单的代码和负责处理它的代码都知道 "keys" 或 "actions",也没有任何字符串在任何地方硬编码。
NonceInterface
和 WpNonce
上面的示例中的两个类接收 NonceInterface
的一个实例。
该接口有 3 个方法
action()
__toString()
validate()
该包只包含一个实现,称为 WpNonce
,它包装 WordPress 函数以创建和验证非ces。
非ces上下文
NonceInterface
的 validate()
方法接收一个可选参数:一个 NonceContextInterface
的实例。
原因是,为了验证它封装的值,非ces 需要知道将其与什么进行比较。
此包将此值称为非ces 值 "上下文"。
非ces 上下文由一个非常简单的接口表示,该接口仅仅是 ArrayAccess
的扩展。
原因在于,即使WordPress对非ces的实现需要将字符串作为“上下文”,其他实现可能需要不同/更多的事物。
例如,我可以想象一个将非ces值存储为用户元的数据的非ces实现,验证非ces是否有效不仅需要值本身,还需要用户ID。
将上下文设置为ArrayAccess
实例,该包为自定义实现提供了最大的灵活性。
RequestGlobalsContext
在上面的示例伪代码中,没有传递任何上下文就调用了validate()
。
原因在于,当未提供时(它是可选的),WpNonce
会创建并使用默认的NonceContextInterface
实现,即RequestGlobalsContext
。
此实现使用超全局变量($_GET
和$_POST
)来填充ArrayAccess
存储,以便在未提供其他上下文时,validate()
实际上使用超全局变量作为上下文。
由于这是WordPress中非ces最常用的用法,这简化了大多数情况下的操作,仍然为非常定制的实现提供了灵活性。
仅举一个例子,可以很容易地构建一个从HTTP头部获取值的NonceContextInterface
实现(在REST上下文中可能很有用),同时仍然可以使用随该包一起提供的WpNonce
类来验证它。
助手
查看上面的示例伪代码,当需要将非ces“嵌入”到HTML表单中时,代码使用add_query_arg()
将非ces动作和值作为URL查询变量添加。
这是在核心中通过wp_nonce_url()
完成的,然而,该函数接受字符串“动作”和“密钥”作为参数,并构建非ces值。
由于我们想要封装非ces值的创建,所以我们实际上不能使用该函数。
为了提供相同级别的“简单性”,该包提供了一个函数Brain\Nonces\nonceUrl()
,它接收一个非ces实例和一个URL字符串,并将非ces动作/值作为URL查询变量添加。
非ces实例是第一个函数参数,与WordPress核心函数不同,URL字符串是可选的,如果未提供,则默认为当前URL。
然而,在HTML表单的情况下,最好使用表单字段而不是URL查询变量。
在WordPress中,这是使用wp_nonce_field()
完成的,此包提供了Brain\Nonces\formField()
,它接收一个非ces实例并返回表单字段的HTML标记。
因此,上述示例伪代码可以更新如下
class TaskForm { public function __construct(\Brain\Nonces\NonceInterface $nonce){ $this->nonce = $nonce; $this->url = admin_url('admin-post.php'); } public function printFrom() { $url = \Brain\Nonces\nonceUrl($this->nonce, $this->url); echo "<form action={$url}>"; // rest of form here... } }
或者甚至更好
class TaskForm { public function __construct(\Brain\Nonces\NonceInterface $nonce){ $this->nonce = $nonce; $this->url = admin_url('admin-post.php'); } public function printFrom() { echo "<form action={$this->url}>"; echo \Brain\Nonces\formField($this->nonce); // rest of form here... } }
注意,这两个辅助函数接受NonceInterface
的实例,而不是WordPress特定的WpNonce
类,因此它们也可以与任何自定义实现一起使用。
WpNonce
是博客特定的
上面提到,WpNonce
类是WordPress函数的包装器。
这是真的,但除了使用wp_create_nonce()
/ wp_verify_nonce()
之外,WpNonce
在调用这两个WordPress函数时,会自动将当前博客ID添加到传递给其构造函数的动作中。
这确保了当非ces在博客上下文中生成时,在其他博客上下文中验证会失败。
这是一个检查,可以避免在多站点上下文中使用插件切换博客时出现的问题,例如保存帖子数据;防止将博客的元数据保存到另一个博客的帖子中。
安装
通过Composer,要求版本~1.0.0
的brain/nonces
。
最低要求
- PHP 5.5+
- Composer来安装
许可证
MIT
贡献
请参阅CONTRIBUTING.md
。
发现安全问题,请不要使用问题跟踪器(也不发送任何拉取请求)。它们是公开的,因此请将电子邮件发送到我的Github个人资料上的地址。谢谢。