FormProtection 组件提供对表单数据篡改的保护。
与所有组件一样,它通过几个可配置参数进行配置。所有这些属性都可以直接设置,也可以通过您控制器中 initialize()
或 beforeFilter()
方法中相同名称的设置方法设置。
如果您使用其他组件,这些组件在其 startup()
回调中处理表单数据,请确保在您的 initialize()
方法中将 FormProtection 组件放在这些组件之前。
注意
使用 FormProtection 组件时,您必须使用 FormHelper 来创建表单。此外,您不能覆盖任何字段的“name”属性。FormProtection 组件会查找由 FormHelper 创建和管理的某些指示器(尤其是那些在 Cake\View\Helper\FormHelper::create()
和 Cake\View\Helper\FormHelper::end()
中创建的)。动态更改在 POST 请求中提交的字段,例如通过 JavaScript 禁用、删除或创建新字段,可能会导致表单令牌验证失败。
默认情况下,FormProtectionComponent
会阻止用户以特定方式篡改表单。它将阻止以下操作:
无法修改表单的 action(URL)。
无法向表单添加未知字段。
无法从表单中删除字段。
无法修改隐藏输入的值。
通过与 FormHelper
协作并跟踪表单中的哪些字段来实现对这些类型篡改的阻止。隐藏字段的值也会被跟踪。所有这些数据都会被组合并转换成一个散列,隐藏令牌字段也会自动插入表单。表单提交时,FormProtectionComponent
会使用 POST 数据构建相同的结构并比较散列。
注意
FormProtectionComponent 不会阻止添加/更改 select 选项。它也不会阻止添加/更改单选按钮选项。
通常在控制器的 initialize()
或 beforeFilter()
回调中配置表单保护组件。
可用的选项包括:
设置为 false
以完全跳过对 POST 请求的验证,本质上是关闭表单验证。
设置为表单字段列表,将其从 POST 验证中排除。可以单独在组件中,或通过 FormHelper::unlockField()
解锁字段。已解锁的字段不需要作为 POST 的一部分,并且隐藏的解锁字段不会检查其值。
要从 POST 验证检查中排除的操作。
验证失败时要调用的回调。必须是一个有效的闭包。默认情况下取消设置,在这种情况下,验证失败时会抛出异常。
namespace App\Controller;
use App\Controller\AppController;
use Cake\Event\EventInterface;
class WidgetsController extends AppController
{
public function initialize(): void
{
parent::initialize();
$this->loadComponent('FormProtection');
}
public function beforeFilter(EventInterface $event)
{
parent::beforeFilter($event);
if ($this->request->getParam('prefix') === 'Admin') {
$this->FormProtection->setConfig('validate', false);
}
}
}
上面的示例将为具有 admin 前缀的路由禁用表单篡改防御。
在某些情况下,您可能希望为某个操作禁用表单篡改防御(例如 AJAX 请求)。您可以通过在您的 beforeFilter()
中将它们列在 $this->FormProtection->setConfig('unlockedActions', ['edit']);
中来“解锁”这些操作。
namespace App\Controller;
use App\Controller\AppController;
use Cake\Event\EventInterface;
class WidgetController extends AppController
{
public function initialize(): void
{
parent::initialize();
$this->loadComponent('FormProtection');
}
public function beforeFilter(EventInterface $event)
{
parent::beforeFilter($event);
$this->FormProtection->setConfig('unlockedActions', ['edit']);
}
}
此示例将为 edit 操作禁用所有安全检查。
如果表单保护验证失败,默认情况下会导致 400 错误。您可以通过在控制器中将 validationFailureCallback
配置选项设置为回调函数来配置此行为。
通过配置回调方法,您可以自定义故障处理过程的工作方式。
public function beforeFilter(EventInterface $event)
{
parent::beforeFilter($event);
$this->FormProtection->setConfig(
'validationFailureCallback',
function (BadRequestException $exception) {
// You can either return a response instance or throw the exception
// received as argument.
}
);
}