donglang2010 2014-11-20 20:11
浏览 19
已采纳

功能测试失败,csrf_protection = true

In a functional test of user registration: when csrf_protection: true, registration fails even though registration succeeds in dev. Test succeeds when csrf_protection: false. (Application uses PUGXMultiUserBundle). I've tried clearing test cache, etc. Dumping $this->client->getResponse()->getContent() to file shows the registration form with all fields but password completed. Stepping through a debug of the test shows the _token field submitted but seemingly stripped out of fos_user_registration_form[] before getting to the line public function request($method, $uri, array $parameters = array(), array $files = array(), array $server = array(), $content = null, $changeHistory = true) in Client.php.

For now I've set csrf_protection: false in config_test.yml - not the best solution!

RegistrationFunctionalTest

namespace Truckee\UserBundle\Tests\Controller;

use Liip\FunctionalTestBundle\Test\WebTestCase;
class RegistrationFunctionalTest extends WebTestCase
{
    private $volunteerValues;
    private $client;

    public function setup()
    {
        $classes = array(
            'Truckee\MatchingBundle\DataFixtures\SampleData\LoadFocusSkillData',
            'Truckee\MatchingBundle\DataFixtures\SampleData\LoadTemplateData',
        );
        $this->loadFixtures($classes);
        $this->client = static::createClient();

        $this->volunteerValues = array(
            'fos_user_registration_form' => array(
                'email' => 'hvolunteer@bogus.info',
                'username' => 'hvolunteer',
                'firstName' => 'Harry',
                'lastName' => 'Volunteer',
                'plainPassword' => array(
                    'first' => '123Abcd',
                    'second' => '123Abcd',
                ),
                'focuses' => array('1'),
                'skills' => array('14'),
            )
        );
    }


    public function submitVolunteerForm()
    {
        $crawler = $this->client->request('GET', '/register/volunteer');
        $form = $crawler->selectButton('Save')->form();
        $this->client->request($form->getMethod(), $form->getUri(), $this->volunteerValues);
    }

    public function testRegisterVolunteer()
    {
        $this->submitVolunteerForm();

        $this->client->enableProfiler();
        if ($profile = $this->client->getProfile()) {
            $mailCollector = $this->client->getProfile()->getCollector('swiftmailer');
             $this->assertEquals(1, $mailCollector->getMessageCount());
        }
        $crawler = $this->client->followRedirect();

        $this->assertTrue($crawler->filter('html:contains("An email has been sent")')->count() > 0);
    }
...
}

registration form (snippet) showing _token

<div class="row">
    <div class="col-md-5">
        {%if form._token is defined %}{{ form_widget(form._token) }}{% endif %}
        {{ form_row(form.firstName) }}
        {{ form_row(form.lastName) }}
    </div>
</div>
  • 写回答

1条回答 默认 最新

  • douxianliu6756 2014-11-21 20:01
    关注

    After much experimentation I discovered my own solution: Add 'intention' => 'registration', to user form class! Doh!

    EDIT: above was NOT the solution!!!

    The fundamental problem was using the array method ($this->client->request($form->getMethod(), $form->getUri(), $this->volunteerValues); of submitting the form. Doing so excluded the csrf token! Instead, I did this to allow the form's token field to be used:

    public function submitVolunteerForm()
    {
        $crawler = $this->client->request('GET', '/register/volunteer');
        $form = $crawler->selectButton('Save')->form();
        $form['fos_user_registration_form[email]'] = 'hvolunteer@bogus.info';
        $form['fos_user_registration_form[username]'] = 'hvolunteer';
        $form['fos_user_registration_form[firstName]'] = 'Harry';
        $form['fos_user_registration_form[lastName]'] = 'Volunteer';
        $form['fos_user_registration_form[plainPassword][first]'] = '123Abcd';
        $form['fos_user_registration_form[plainPassword][second]'] = '123Abcd';
        $form['fos_user_registration_form[focuses]'] = [1];
        $form['fos_user_registration_form[skills]'] = [14];
    
        $crawler = $this->client->submit($form);
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 DIFY API Endpoint 问题。
  • ¥20 sub地址DHCP问题
  • ¥15 delta降尺度计算的一些细节,有偿
  • ¥15 Arduino红外遥控代码有问题
  • ¥15 数值计算离散正交多项式
  • ¥30 数值计算均差系数编程
  • ¥15 redis-full-check比较 两个集群的数据出错
  • ¥15 Matlab编程问题
  • ¥15 训练的多模态特征融合模型准确度很低怎么办
  • ¥15 kylin启动报错log4j类冲突