2010-02-20 2 views
9

Symfony에서 CSRF 보호가 활성화 된 양식을 테스트하기위한 기능 테스트를 만드는 가장 좋은 방법은 무엇입니까?symfony에서 CSRF가 활성화 된 기능 테스트 양식

현재 I는 각 양식의 submittion 앞에 다음 코드를 추가해야합니다 :

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

나는 추가 토큰 $와 같은 매개 변수를 형성 $ TOKEN_NAME :이 옵션은에 제안

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

을 문서 :

'_with_csrf' => true, 

전혀 작동하지 않습니다.

수동으로 테스트 한 각 양식에 토큰을 추가하지 않으려면 더 간단한 방법이 있습니까? 아니면 테스트를 실행할 때 csrf 점검을 끄는 방법이 있습니까?

위에서 설명한 방법은 1-2 개의 폼을 테스트해야 할 때 괜찮습니다.하지만 프로젝트에 수십 개의 고유 한 폼이 포함되어 있으면 고통이됩니다.

+0

T 그 문서 옵션은 BaseForm의 인스턴스를 사용하여 확장합니다. CSRF 토큰은 양식 유형을 사용하여 생성되기 때문에 MyFooForm! = BaseForm 따라서 옵션이 실패하는 이유입니다 ... 옵션은 내 프로젝트에서도 그렇게했습니다. – richsage

+0

실패하는 또 다른 이유가 있습니다. csrf 토큰을 매개 변수 목록에 추가하지만 대개 배열 형태입니다 (위의 예제와 같이). 따라서 완전히 쓸모가 없습니다 :-(. 귀하의 의견을 보내 주셔서 감사합니다. – Stepashka

답변

4

물론 url을 직접 호출하면 _with_csrf 옵션을 사용할 수 없습니다. 제출 단추를 클릭하여 양식 페이지에서 전달해야합니다. 과 같이 :

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

문자열 '로그인 절차는'양식에 적응해야합니다. 양식의 ID를 적용하여 'signin'대신 'form # myform input [type = "submit"]'과 같은보다 레이블에 독립적 인 문자열을 사용할 수도 있습니다.

이미 제안했듯이 로그인을 위해 CSRF를 사용할 수 없으므로 데이터를 수정하는 양식에 유용합니다.

3

저는 개인적으로 광범위하게 기능 테스트를 사용하지 않지만 테스트 목적으로 폼 클래스에서 항상 CSRF 보호 기능을 해제 할 수 있습니다.

public function configure() 

    $this->disableLocalCSRFProtection(); 
0

환경 테스트를 위해 CSRF를 해제합니다.

0

양식이 포함 된 페이지를 표시하여 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'); 
당신은 단지 추가 컴파일러 패스를 추가하여 모든 형태에 대한 CSRF 보호를 해제 할 수 있습니다
1

:

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

또는 설정에 추가하여 완전히 형태의 확장을 해제 할 수 있습니다 : BTW

framework: 
    csrf_protection: false 

, 마지막 솔루션은 양식 옵션을 명시 적으로 설정하지 않은 경우에만 작동합니다. csrf_protection