2010-04-05 6 views
7

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

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

Спасибо.

ответ

5

Единственный способ, по-видимому, переписать 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!

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

+0

@naag: Большое спасибо. Пробовал несколько вещей, но не тот, будет играть. Похоже на незначительный надзор со стороны симфонии. – Tom

+0

Я отредактировал свой ответ, чтобы включить проверку наличия валидатора CSRF :-) – naag

2

В 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 токен:» немного по-прежнему отображается в сообщении об ошибке, хотя.

1

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

3

Ни один из этих ответов не объясняет, как удалить метку «CSRF-токен:», которая префиксарует сообщение об ошибке нехитрым способом (например, изменение имени токена - плохая идея!).

Единственный звуковой способ удаления ярлыка - расширить возможности проверки подлинности 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

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

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", добавляя имя и двоеточие. Будьте осторожны, поскольку он изменяет значение для всех форм и всех глобальных ошибок.

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