2017-03-06 45 views
0

我知道該主題已在SO中進行了多次討論,但我已經檢查了大量主題沒有人像我的一樣,到目前爲止我所測試的並不是解決我的問題。首先我使用的是Symfony 3.2.4和PHP 7.1.2。_token在POST數據中出現,但是表單失敗,出現錯誤:「CSRF令牌無效,請嘗試重新提交表單」

我在我的控制器下面的代碼:

class QuoteController extends Controller 
{ 
    /** 
    * @Route("/quote/register") 
    */ 
    public function registerAction() 
    { 
     $entity = new Quote(); 
     $form = $this->createForm(QuoteType::class, $entity); 

     return $this->render(
      'QuoteBundle:Quote:register.html.twig', 
      ['entity' => $entity, 'form' => $form->createView()] 
     ); 
    } 

    /** 
    * @Route("/quote/save", name="save-quote") 
    */ 
    public function saveAction() 
    { 
     $entity = new Quote(); 
     $form = $this->createForm(QuoteType::class, $entity); 

     $request = Request::createFromGlobals(); 
     $form->handleRequest($request); 

     if ($form->isValid()) { 
      dump($form->getData()); 
     } else { 
      dump($_POST); 
      dump($form->getErrors()); 
     } 

     die(); 
    } 
} 

這是怎麼了我的QuoteType樣子:

class QuoteType extends AbstractType 
{ 
    /** 
    * @param FormBuilderInterface $builder 
    * @param array    $options 
    */ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder 
      ->add('schneider_quote_id') 
      ->add('agreement_number') 
      ->add('quote_creation_source') 
      ->add('quote_status') 
      ->add('distributor_id') 
      ->add('start_date', DateType::class) 
      ->add('end_date', DateType::class) 
      ->add('save', SubmitType::class, ['label' => 'Create Post']); 
    } 

    /** 
    * @param OptionsResolverInterface $resolver 
    */ 
    public function setDefaultOptions(OptionsResolverInterface $resolver) 
    { 
     $resolver->setDefaults([ 
      'data_class' => Quote::class, 
     ]); 
    } 

    /** 
    * @return string 
    */ 
    public function getName() 
    { 
     return 'quote'; 
    } 
} 

最後,這是我的模板寄存器的樣子:

{% block body %} 
    {{ form_start(form, {'action': path('save-quote'), 'method': 'POST'}) }} 
    {{ form_errors(form) }} 
    {{ form_widget(form) }} 
    {{ form_row(form._token) }} 
    {{ form_end(form) }} 
{% endblock %} 

但是當我發送表單時,我得到了錯誤:

The CSRF token is invalid. Please try to resubmit the form.

如果您發現我有形式錯誤當中dump()$_POST數據,這是結果:

dump($_POST); 
array:1 [▼ 
    "quote" => array:9 [▼ 
    "schneider_quote_id" => "100" 
    "agreement_number" => "100" 
    "quote_creation_source" => "sdasdasd" 
    "quote_status" => "sadsad" 
    "distributor_id" => "2" 
    "start_date" => array:3 [▶] 
    "end_date" => array:3 [▶] 
    "save" => "" 
    "_token" => "bSuU7h7rDR-_FkEGZ3zS60OtIofs_1bAi-J-YdCtxlM" 
    ] 
] 

dump($form->getErrors()); 
FormErrorIterator {#32 ▼ 
    -form: Form {#672 ▼ 
    -config: FormBuilder {#673 ▶} 
    -parent: null 
    -children: OrderedHashMap {#674 ▶} 
    -errors: array:1 [▼ 
     0 => FormError {#625 ▶} 
    ] 
    -submitted: true 
    -clickedButton: SubmitButton {#787 ▶} 
    -modelData: Quote {#444 ▶} 
    -normData: Quote {#444 ▶} 
    -viewData: Quote {#444 ▶} 
    -extraData: [] 
    -transformationFailure: null 
    -defaultDataSet: true 
    -lockSetData: false 
    } 
    -errors: array:1 [▼ 
    0 => FormError {#625 ▼ 
     -message: "The CSRF token is invalid. Please try to resubmit the form." 
     #messageTemplate: "The CSRF token is invalid. Please try to resubmit the form." 
     #messageParameters: [] 
     #messagePluralization: null 
     -cause: null 
     -origin: Form {#672} 
    } 
    ] 
} 

問題是爲什麼,如果_token存在於POST數據不被讀取由Symfony正確?

我已經從The Form Components讀了CSRF Protection的文檔,現在我很困惑,也許事情在Symfony 3中發生了變化,我不知道。我是否需要以某種方式在我的控制器中創建這段代碼?

use Symfony\Component\Form\Forms; 
use Symfony\Component\HttpFoundation\Session\Session; 
use Symfony\Component\Form\Extension\Csrf\CsrfExtension; 
use Symfony\Component\Security\Csrf\TokenStorage\SessionTokenStorage; 
use Symfony\Component\Security\Csrf\TokenGenerator\UriSafeTokenGenerator; 
use Symfony\Component\Security\Csrf\CsrfTokenManager; 

// create a Session object from the HttpFoundation component 
$session = new Session(); 

$csrfGenerator = new UriSafeTokenGenerator(); 
$csrfStorage = new SessionTokenStorage($session); 
$csrfManager = new CsrfTokenManager($csrfGenerator, $csrfStorage); 

$formFactory = Forms::createFormFactoryBuilder() 
    // ... 
    ->addExtension(new CsrfExtension($csrfManager)) 
    ->getFormFactory(); 

爲什麼我在這裏失蹤?

+0

您的網站連接在https下?如果是,則必須確保在'true'上設置參數'cookie_secure'(在'config.yml'的'session'部分下),否則所有csfr令牌都將失效。 –

+0

@gp_sflover不,不幸的是,情況並非如此 – ReynierPM

+0

替換「{{form_row(form._token)}}」與「{{form_rest(form)}}」 – pogeybait

回答

0

經過幾次頭痛後,我終於找到問題來自哪裏。這是我session部分看起來像我的config.yml

session: 
    storage_id: session.storage.php_bridge 
    handler_id: ~ 
    save_path: ~ 

改變上述配置這一個:

session: 
    handler_id: session.handler.native_file 
    save_path: ~ 

因此很明顯,~不設置默認handler_id可言。

相關問題