有人能告诉我在Symfony 1.4中如何自定义表单CSRF令牌错误消息吗?我正在使用sfDoctrineGuard进行登录,在这个表单中,每当会话过期且页面仍然打开时,它会抛出一个非常不友好的错误:“检测到CSRF攻击”。类似“此会话已过期。请返回主页并重试”听起来更好。
在表单类中正确的方法是什么?
谢谢。
sfForm::addCSRFProtection()
方法。
在 /lib/form/BaseForm.class.php
中,您可以添加以下代码:
class BaseForm extends sfFormSymfony
{
public function addCSRFProtection($secret = null)
{
parent::addCSRFProtection($secret);
if (array_key_exists(self::$CSRFFieldName, $this->getValidatorSchema())) {
$this->getValidator(self::$CSRFFieldName)->setMessage('csrf_attack', 'This session has expired. Please return to the home page and try again.');
}
}
}
csrf_attack
的消息。请注意,您还需要检查验证器是否存在。有些表单可能已经禁用了它们的CSRF保护!希望这可以帮到您!这些答案都没有说明如何以非hackish的方式(例如更改令牌名称是不好的想法!)删除在错误消息前缀中添加“CSRF token:”标签的方法。
唯一可靠的方法是扩展CSRF验证器以抛出全局错误。 在此过程中,我们还可以更改错误消息。
class myValidatorCSRFToken extends sfValidatorCSRFToken
{
protected function configure($options = array(), $messages = array())
{
parent::configure($options, $messages);
$this->addMessage('csrf_attack', 'Your session has expired. Please return to the home page and try again.');
}
protected function doClean($value)
{
try {
return parent::doClean($value);
} catch (sfValidatorError $e) {
throw new sfValidatorErrorSchema($this, array($e));
}
}
}
public function addCSRFProtection($secret = null)
{
parent::addCSRFProtection($secret);
if (isset($this->validatorSchema[self::$CSRFFieldName])) //addCSRFProtection doesn't always add a validator
{
$this->validatorSchema[self::$CSRFFieldName] = new myValidatorCSRFToken(array(
'token' => $this->validatorSchema[self::$CSRFFieldName]->getOption('token')
));
}
}
public function addCSRFProtection($secret = null)
{
parent::addCSRFProtection($secret);
if (isset($this->validatorSchema[self::$CSRFFieldName])) {
$this->validatorSchema[self::$CSRFFieldName]->setMessage('csrf_attack', 'This session has expired. Please refresh and try again.');
}
}
在之前的答案基础上,这是我使用的代码:
public function addCSRFProtection($secret = null)
{
parent::addCSRFProtection($secret);
if (isset($this->validatorSchema[self::$CSRFFieldName])) {
$this->validatorSchema[self::$CSRFFieldName]->setMessage('csrf_attack', 'This session has expired. Please refresh and try again.');
$this->getWidgetSchema()->getFormFormatter()->setNamedErrorRowFormatInARow(" <li>%error%</li>\n");
}
}
"<li>%name%: %error%</li>\n"
,添加了名称和冒号。请注意,这将更改所有表单和全局错误的值。我认为“csrf token:”前缀可以通过全局设置CSRF令牌字段的标签来删除或自定义。
使用事件分发器。看看这个http://bluehorn.co.nz/2010/07/15/how-to-change-csrf-attack-message-in-symfony-1-2/
我写的是针对Symfony 1.2的,但是使用了事件分发器,所以它可能仍然适用于Symfony 1.4。