簡體   English   中英

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

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

每次嘗試提交表單時,我都會收到此錯誤消息:

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>

有任何想法嗎?

您需要在表單中添加_token ,即

{{ form_row(form._token) }}

截至目前,您的表單缺少 CSRF 令牌字段。 如果您使用 twig 表單函數來呈現表單,例如form(form)這將自動為您呈現 CSRF 令牌字段,但您的代碼顯示您正在使用原始 HTML 呈現表單,例如<form></form> ,因此您必須手動渲染該字段。

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

根據文檔

這將呈現尚未為給定表單呈現的所有字段。 始終將它放在表單中的某個地方是個好主意,因為它會為您呈現隱藏字段並使您忘記呈現的任何字段更加明顯(因為它會為您呈現該字段)。

form_rest(視圖,變量)

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

php.ini 中的這個選項導致問題

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

問題是 _token 字段未命中 PUT (GET) 請求,因此您必須增加值。

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

upload_max_filesize

選項將解決問題。

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

您可以在getDefaultOptions方法中的表單類中禁用此 CSRF 保護,如下所示:

// Other methods omitted

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

如果您不想禁用 CSRF 保護,則需要在表單中呈現 CSRF 保護字段。 可以通過在視圖文件中使用{{ 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) }}呈現您尚未手動輸入的所有字段。

在你的</form>標簽之前:

{{ form_rest(form) }}

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

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

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

除了其他人的建議之外,如果您的會話存儲不工作,您可能會收到 CSRF 令牌錯誤。

在最近的一個案例中,我的一位同事將“session_prefix”更改為一個包含空格的值。

session_prefix: 'My Website'

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

如果您已將表單從純 HTML 轉換為 twig,請確保您沒有遺漏刪除結束</form>標記。 愚蠢的錯誤,但正如我發現的那樣,這可能是導致此問題的原因。

當我遇到這個錯誤時,一開始我無法弄清楚。 我正在使用form_start()form_end()來生成表單,因此我不必使用form_row(form._token)顯式添加令牌,或者使用form_rest()來獲取它。 它應該已經由form_end()自動添加。

問題是,我正在使用的視圖是我從純 HTML 轉換為 twig 的視圖,並且我錯過了刪除結束</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>

顯然,解決方案是刪除多余的結束標簽,然后再喝一些咖啡。

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

我最近遇到了同樣的問題,我的案例在這里還沒有提到:

問題是我在localhost域上測試它。 我不確定為什么這是一個問題,但是在我將localhost的主機名別名添加到/etc/hosts后它開始工作,如下所示:

127.0.0.1        foobar

使用 Apache 和localhost作為域時,會話可能有問題。 如果有人可以在評論中詳細說明,我很樂意編輯此答案以包含更多詳細信息。

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

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

就我而言,實體中的 maxSize 注釋出現問題,因此我將其從 2048 增加到 20048。

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

希望這個答案有幫助!

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

修復:清除相關域的所有 cookie,確保您沒有在具有不同端口的同一域上運行多個應用程序。

我有同樣的錯誤,但就我而言,問題是我的應用程序使用了多個一級域,而 cookie 使用了一個。 config.yml framework.session中刪除cookie_domain: ".%domain%"導致 cookie 默認為表單所在的任何域,這解決了問題。

您需要記住 CSRF 令牌存儲在會話中,因此由於會話處理無效,也會出現此問題。 如果您在 localhost 上工作,請檢查例如會話 cookie 域是否設置正確(在 PHP 中,在 localhost 上它應該是空的)。

這在使用引導程序時似乎是一個問題,除非您通過 {{ form(form)}} 呈現表單。 此外,問題似乎只發生在 input type="hidden" 上。 如果您使用表單檢查頁面,您會發現隱藏的輸入根本不是標記的一部分,或者它正在呈現但由於某種原因未提交。 如上所述,添加 {{form_rest(form)}} 或像下面這樣包裝輸入應該可以解決問題。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM