Форма функционального тестирования с включенной CSRF в Symfony - PullRequest
9 голосов
/ 20 февраля 2010

Каков наилучший способ создания функциональных тестов для тестирования форм с включенной защитой CSRF в Symfony?

В настоящее время я должен добавить следующий код перед каждой отправкой формы:

  $form = new sfGuardFormSignin();
  $token = $form->getCSRFToken();
  $token_name = $form->getCSRFFieldName();

Затем я добавляю $ token и $ token_name, чтобы сформировать такие параметры:

call('/login', 'POST', array (
    'signin' => 
    array (
      'username' => $username,
      'password' => $password,
      $token_name => $token,
    )))

Вариант, предложенный в документации:

'_with_csrf' => true,

Не работает вообще.

Есть ли более простой способ избежать добавления токена в каждую форму, проверенную вручную? Или есть способ отключить проверку csrf при запуске тестов?

Способ, который я описал выше, подходит для тестирования 1-2 форм, но если проект содержит десятки уникальных форм, это становится болью.

Ответы [ 5 ]

4 голосов
/ 17 июня 2010

Конечно, вы не можете использовать параметр _with_csrf, если вы вызываете непосредственно URL. Вы должны перейти со страницы формы, нажав на кнопку отправки. Вот так:

click('signin', array('signin' => array('username' => $username, 'password' => $password), array('_with_csrf' => true)))

Строка 'signin' должна быть адаптирована к вашей форме. Вы также можете использовать более независимую от метки строку, например «form # myform input [type =" submit »]» вместо «signin», адаптируя идентификатор вашей формы.

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

3 голосов
/ 20 февраля 2010

Лично я не использую функциональные тесты, которые широко (вероятно, в мою пользу), но вы всегда можете отключить защиту CSRF в своем классе формы для целей тестирования.

public function configure ()

  $this->disableLocalCSRFProtection();
1 голос
/ 02 марта 2016

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

class CsrfProtectionCompilerPass implements CompilerPassInterface
{
    /**
     * {@inheritdoc}
     */
    public function process(ContainerBuilder $container)
    {
        $env = $container->getParameter('kernel.environment');
        if ($env == 'test') {
            $container->setParameter('form.type_extension.csrf.enabled', false);
        }
    }
}

Или Вы можете полностью отключить расширение формы, добавив в config:

framework:
    csrf_protection: false

Кстати, последние решения работают только в том случае, если у вас явно не установлен параметр формы csrf_protection

0 голосов
/ 29 октября 2012

Вы должны получить токен CSRF, указав страницу с формой.

$browser->get('/login');
$dom = new DOMDocument('1.0', $browser->getResponse()->getCharset());
$dom->loadHTML($browser->getResponse()->getContent());
$domCssSelector = new sfDomCssSelector($dom);
$token = $domCssSelector->matchSingle('input[name="_csrf_token"]')->getNode()->getAttribute('value');
0 голосов
/ 01 марта 2010

Я бы отключил CSRF для тестирования среды.

...