2012-03-01 39 views
14

Tôi đang viết kiểm tra chức năng và tôi cần thực hiện yêu cầu đăng bài ajax. "Mã thông báo CSRF không hợp lệ. Vui lòng gửi lại biểu mẫu". Làm thế nào tôi có thể nhận được mã thông báo trong bài kiểm tra chức năng của tôi?Nhận mã thông báo CSRF trong thử nghiệm

$crawler = $this->client->request(
    'POST', 
    $url, 
    array(
     'element_add' => array(
      '_token' => '????', 
      'name' => 'bla', 
    ) 

), 
    array(), 
    array('HTTP_X-Requested-With' => 'XMLHttpRequest') 
); 

Trả lời

18

Trình tạo mã thông báo CSRF là dịch vụ symfony 2 bình thường. Bạn có thể nhận dịch vụ và tự tạo mã thông báo. Ví dụ:

$csrfToken = $client->getContainer()->get('form.csrf_provider')->generateCsrfToken('registration'); 
    $crawler = $client->request('POST', '/ajax/register', array(
     'fos_user_registration_form' => array(
      '_token' => $csrfToken, 
      'username' => 'samplelogin', 
      'email' => '[email protected]', 
      'plainPassword' => array(
       'first' => 'somepass', 
       'second' => 'somepass', 
      ), 
      'name' => 'sampleuser', 
      'type' => 'DSWP', 
     ), 
    )); 

Các generateCsrfToken được một tham số quan trọng ý mà nên giống nhau trong các thử nghiệm và theo hình thức nếu không nó bị lỗi.

+0

Làm thế nào biết tham số $ intention được sử dụng trong biểu mẫu là gì? – bux

+0

bạn có thể sử dụng bất kỳ ý định $ nào bạn muốn, chỉ cần đảm bảo rằng nó giống như bạn sử dụng để kiểm tra mã thông báo – Gigala

+3

Trong Symfony 3, dịch vụ được trả về bởi '-> get ('form.csrf_provider')' không được chấp nhận. Sử dụng '-> get ('security.csrf.token_manager')' để thay thế. – iisisrael

11

Sau khi tìm kiếm dài (tôi đã tìm thấy không có gì trong doc và trên mạng về làm thế nào để lấy CSRF token) tôi tìm thấy một cách:

$extract = $this->crawler->filter('input[name="element_add[_token]"]') 
    ->extract(array('value')); 
$csrf_token = $extract[0]; 

Giải nén token từ phản ứng trước khi đưa ra yêu cầu.

+0

này hoạt động, nhưng nó phụ thuộc vào mục đích của thử nghiệm: nếu đó là một bài kiểm tra hành vi, sao chép hành vi của trình duyệt, sau đó nó chắc chắn là con đường để đi (đó là những gì một loại trình duyệt nào); nhưng nếu đó là một thử nghiệm tích hợp, kiểm tra bộ điều khiển được tích hợp đúng với khung công tác CSRF, thì tốt nhất là nên đi qua trình quản lý mã thông báo nếu bạn có thể. –

5

Trong symfony 3, trong WebTestCase của bạn, bạn cần phải nhận được CSRF token:

$csrfToken = $client->getContainer()->get('security.csrf.token_manager')->getToken($csrfTokenId); 

Để có được $csrfTokenId, cách tốt nhất là to force it in the options của bạn FormType():

class TaskType extends AbstractType 
{ 
    // ... 

    public function configureOptions(OptionsResolver $resolver) 
    { 
     $resolver->setDefaults(array(
      'csrf_token_id' => 'task_item', 
     )); 
    } 

    // ... 
} 

Vì vậy, trong trường hợp này: $csrfTokenId = "task_item";. Hoặc bạn, bạn có thể thử sử dụng giá trị mặc định, đó sẽ là tên của biểu mẫu của bạn.

Sau đó, sử dụng nó như một bài tham số:

$client->request(
    'POST', 
    '/url', 
    [ 
    'formName' => [ 
     'field' => 'value', 
     'field2' => 'value2', 
     '_token' => $csrfToken 
    ] 
    ] 
); 
+0

Đây là câu trả lời hiện đại cho symfony3 và cần được chủ động hơn. Nó kết hợp thông tin từ câu trả lời được chấp nhận, nhận xét của nó và hoàn thành với cách được thiết lập bằng cách đặt '$ tokenId' –

Các vấn đề liên quan