2014-05-04 195 views
22

每次我嘗試提交表格時,我收到此錯誤信息:CSRF令牌無效。請嘗試重新提交表單

的CSRF令牌無效。請嘗試重新提交表單

我的表單代碼是這樣的:

<form novalidate action="{{path('signup_index')}}" method="post" {{form_enctype(form)}} role="form" class="form-horizontal"> 
    <div class="form-group"> 
     {{ form_label(form.email, 'Email', {'label_attr': {'class': 'col-md-1 control-label'}}) }} 
     {{ form_widget(form.email, {'attr': {'class': 'col-md-2'}}) }} 
     {{ form_errors(form.email) }} 
    </div> 

    <div class="form-group"> 
     {{ form_label(form.nickname, 'Nickname', {'label_attr': {'class': 'col-md-1 control-label'}}) }} 
     {{ form_widget(form.nickname, {'attr':{'class': 'col-md-2'}}) }} 
     {{ form_errors(form.nickname, {'attr': {'class': 'col-md-3'}}) }} 
    </div> 
    <div class="form-group"> 
     {{ form_label(form.password, 'password', {'label_attr': {'class': 'col-md-1 control-label'}}) }} 
     {{ form_widget(form.password, {'attr': {'class': 'col-md-2'}}) }} 
     {{ form_errors(form.password, {'attr': {'class': 'col-md-3'}}) }} 
    </div> 

    <div class="form-group"> 
     {{ form_label(form.password_repeat, 'Repeat password', {'label_attr': {'class': 'col-md-1 control-label'}}) }} 
     {{ form_widget(form.password_repeat, {'attr':{'class': 'col-md-2'}}) }} 
     {{ form_errors(form.password_repeat, {'attr': {'class': 'col-md-3'}}) }} 
    </div> 
    <div class="form-group"> 
     <div class="col-md-1 control-label"> 
     <input type="submit" value="submit"> 
    </div> 

    </div> 
</form> 

任何想法?

+0

@MKhalidJunaid你爲什麼保護這個? – Undo

回答

67

您需要在您的表單中添加的_token

{{ form_row(form._token) }} 

截至目前您的形式缺少CSRF令牌場。如果您使用樹枝表單功能來呈現您的表單,例如form(form),則會自動爲您呈現CSRF標記字段,但是您的代碼顯示您正在使用原始HTML呈現您的表單,如<form></form>,因此您必須手動呈現該字段。

或者,只需在表單的結束標記之前添加{{ form_rest(form) }}即可。

根據文檔

這使得尚未被渲染爲給定的 形式的所有領域。在你的表格 內部總是有這樣一個好主意,因爲它會爲你呈現隱藏的字段,並讓你忘記 的任何字段變得更明顯(因爲它會爲你渲染字段)。

form_rest(view, variables)

+3

{{form_rest(form)}}對我來說是最好的。謝謝,+1 – voghDev

3

之前您</form>標籤放:

{{ form_rest(form) }} 

它會自動插入其他重要的(隱藏)的投入。

5

發生這種情況是因爲表單默認包含CSRF保護,在某些情況下這不是必需的。

可以在getDefaultOptions方法禁用窗體類此CSRF保護這樣的:

// Other methods omitted 

public function getDefaultOptions(array $options) 
{ 
    return array(
     'csrf_protection' => false, 
     // Rest of options omitted 
    ); 
} 

如果你不想禁用CSRF保護,那麼你就需要呈現在您的形式CSRF protecion場。它可以通過在視圖文件中使用{{ form_rest(form) }},這樣做:

<form novalidate action="{{path('signup_index')}}" method="post" {{form_enctype(form)}} role="form" class="form-horizontal"> 
    <!-- Code omitted --> 

    <div class="form-group"> 
     <div class="col-md-1 control-label"> 
      <input type="submit" value="submit"> 
     </div> 

    </div> 
    {{ form_rest(form) }} 
</form> 

{{ form_rest(form) }}呈現一個你沒有手動輸入所有字段。

0

如果你不想使用form_row或form_rest只想訪問你的樹枝模板中_token的值。使用以下內容:

<input type="hidden" name="form[_token]" value="{{ form._token.vars.value }}" /> 
16

如果您的表單中有很多元素,您也可以看到此錯誤消息。

這個選項在php中。問題

; How many GET/POST/COOKIE input variables may be accepted 
max_input_vars = 1000 

問題INI原因是_token遺漏PUT(GET)請求 所以,你可以增加價值。

此外,它涉及一個大文件。增加

upload_max_filesize 

選項將解決問題

+1

在我的情況下,它是post_max_size + upload_max_filesize –

-1

這似乎用引導時,除非你是通過渲染的形式是一個問題{{表單(form)}}。此外,這些問題似乎只發生在輸入類型=「隱藏」。如果你用表單檢查頁面,你會發現隱藏的輸入根本不是標記的一部分,或者它正在呈現,但不是由於某種原因提交的。如上所述,添加{{form_rest(form)}}或者像下面一樣包裝輸入應該能夠做到這一點。

<div class="form-group"> 
    <input type="hidden" name="_csrf_token" value="{{ csrf_token('authenticate') }}"> 
</div> 
+0

沒有工作csrf_token('authenticate') – fdrv

0

在我來說,我得到了與在實體的最大範圍註釋的麻煩,所以我增加了從2048到20048.

/** 
* @Assert\File(
*  maxSize = "20048k", 
*  mimeTypes = {"application/pdf", "application/x-pdf"}, 
*  mimeTypesMessage = "Please upload a valid PDF" 
*) 
*/ 
private $file; 

希望這個答案可以幫助!

1

除了別人的建議,如果會話存儲不能正常工作,您可以獲得CSRF令牌錯誤。

在最近的一個案例中,我的一位同事將'session_prefix'更改爲一個有空格的值。

session_prefix: 'My Website' 

這打亂了會話存儲,這反過來意味着我的表單無法從會話中獲取CSRF令牌。

+0

相關的疑難雜症是無效控制器中的會話。 – Acyra

0

如果您已將表單從純HTML轉換爲樹枝,請確保您沒有錯過刪除結束標記</form>。愚蠢的錯誤,但我發現這是造成這個問題的可能原因。

當我得到這個錯誤時,我一開始就搞不懂。我使用form_start()form_end()來生成表單,所以我不應該明確添加標記form_row(form._token),或使用form_rest()來獲取它。 It should have already been added automatically by form_end().

的問題是,我用工作的觀點是一個,我已經從普通的HTML轉換爲小枝,我已經錯過刪除閉合</form>標籤,所以不是:

{{ form_end(form) }} 

我:

</form> 
{{ form_end(form) }} 

這實際上似乎喜歡的事,可能會引發錯誤,但顯然沒有,所以當form_end()輸出form_rest(),形式已經關閉。表單的實際生成的頁面來源是這樣的:

<form> 
    <!-- all my form fields... --> 
</form> 
<input type="hidden" id="item__token" name="item[_token]" value="SQAOs1xIAL8REI0evGMjOsatLbo6uDzqBjVFfyD0PE4" /> 
</form> 

顯然,解決方法是刪除多餘的結束標記,也許喝點兒咖啡。

0

我有一個奇怪的行爲:清除瀏覽器緩存沒有解決它,但清除cookie(即PHP會話ID cookie)確實解決了這個問題。

這做後,你已經檢查了所有其他的答案,包括驗證你有一個隱藏的表單輸入字段令牌。

1

我最近有這個錯誤。原來我的cookie設置在config.yml中不正確。將cookie_pathcookie_domain設置添加到framework.session固定它。

0

我遇到過類似的問題。確保令牌字段實際呈現後(請參閱接受的答案),我檢查了我的Cookie。 我的Chrome瀏覽器中存在2個域名(!),顯然是因爲我在另一個應用程序所在的域中運行應用程序,但使用了不同的端口(即mydomain.com設置了原始cookie,運行在mydomain.com:123) 現在顯然Chrome發送了錯誤的cookie,因此CSRF保護無法將令牌鏈接到正確的會話。

修復:清除有問題的域的所有cookie,確保不要在具有不同端口的同一域中運行多個應用程序。

相關問題