Symfony 1.4: пользовательское сообщение об ошибке для CSRF в формах - PullRequest
7 голосов
/ 05 апреля 2010

Может кто-нибудь сказать мне, где / как настроить сообщение об ошибке токена CSRF для форм в Symfony 1.4. Я использую sfDoctrineGuard для входа в систему и, в частности, в этой форме, когда сеанс заканчивается и у вас все еще открыта страница, он выдает очень недружественную пользователю ошибку: «Обнаружена атака CSRF». Что-то вроде «Этот сеанс истек. Пожалуйста, вернитесь на домашнюю страницу и повторите попытку» звучит лучше.

Как правильно сделать это в классе формы?

Спасибо.

Ответы [ 6 ]

5 голосов
/ 06 апреля 2010

Кажется, единственный способ переписать 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, и изменяете сообщение для кода csrf_attack.

Редактировать: Вам также необходимо проверить, существует ли валидатор. В некоторых формах защита CSRF может быть отключена!

Надеюсь, это поможет!

3 голосов
/ 22 апреля 2011

Ни один из этих ответов не объясняет, как удалить метку "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));
    }
  }
}

Теперь давайте настроим наши формы для использования этого валидатора, переопределив sfForm::addCSRFProtection в BaseForm:

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')
    ));
  }
}
2 голосов
/ 28 сентября 2012

Улучшение предыдущих ответов, вот код, который я использую:

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");
    }
  }

Значением по умолчанию для NamedErrorRowFormatInARow является "<li>%name%: %error%</li>\n" с добавлением имени и двоеточия. Будьте осторожны, потому что это изменяет значение для всех форм и всех глобальных ошибок.

Вы также можете изменить поле, создав пользовательский форматировщик форм и используя его в нужных формах. Вы можете посмотреть на документацию здесь для получения дополнительной информации об этом.

2 голосов
/ 21 мая 2010

В 1.4.4 мне пришлось изменить код Наага, например, так ...

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.');
  }
}

Это сработало, бит csrf token: все равно появляется в сообщении об ошибке.

1 голос
/ 19 января 2011

Полагаю, префикс "csrf token:" можно удалить или настроить, установив метку поля токена CSRF, конечно, глобально.

1 голос
/ 15 июля 2010

Использовать диспетчер событий. Проверьте это http://bluehorn.co.nz/2010/07/15/how-to-change-csrf-attack-message-in-symfony-1-2/

Я написал его для Symfony 1.2, но с помощью диспетчера событий, поэтому он все еще может работать для Symfony 1.4.

...