フォームを送信しようとするたびにこのエラーメッセージが表示されます。
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トークンフィールドが自動的にレンダリングされますが、コードは<form></form>
のような生のHTMLでフォームをレンダリングしていることを示しますフィールドを手動でレンダリングする必要があります。
または、単にフォームの終了タグの前に{{ form_rest(form) }}
を追加します。
ドキュメントによると
これにより、指定されたフォームに対してまだレンダリングされていないすべてのフィールドがレンダリングされます。非表示フィールドをレンダリングし、(フィールドをレンダリングするため)レンダリングするのを忘れたフィールドをより明確にするため、常にフォーム内のどこかにこれを配置することをお勧めします。
また、フォームに多くの要素がある場合、このエラーメッセージが表示されます。
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) }}
他の重要な(隠された)入力を自動的に挿入します。
他のユーザーの提案に加えて、セッションストレージが機能していない場合、CSRFトークンエラーが発生する可能性があります。
最近のケースでは、私の同僚が「session_prefix」をスペースのある値に変更しました。
session_prefix: 'My Website'
これによりセッションストレージが破損したため、フォームからセッションからCSRFトークンを取得できませんでした。
この問題には奇妙な振る舞いがありました。ブラウザーのキャッシュをクリアしても解決しませんでしたが、Cookie(つまり、PHPセッションID Cookie)をクリアすると問題は解決しました。
これを行う必要があります後他のすべての回答を確認しました。これには、あなたの確認も含まれますdo隠しフォームの入力フィールドにトークンがあります。
最近このエラーが発生しました。 config.ymlのcookie設定が間違っていたことがわかりました。 cookie_path
設定とcookie_domain
設定をframework.session
に追加すると修正されました。
私は最近同じ問題を抱えており、私の場合はまだここで言及されていないものでした:
問題は、localhost
ドメインでテストしていたことです。なぜこれが正確に問題であったのかはわかりませんが、localhost
のホスト名エイリアスを/etc/hosts
に次のように追加すると、問題が解決し始めました。
127.0.0.1 foobar
Apacheとlocalhost
をドメインとして使用しているときに、おそらくセッションに何か問題があります。誰もがコメントで詳しく説明できる場合は、この回答を編集して詳細を追加します。
同様の問題に直面しました。トークンフィールドが実際にレンダリングされたことを確認した後(受け入れられた回答を参照)、Cookieをチェックしました。 Chromeブラウザーにはドメインの2(!)Cookieがありました。これは、アプリケーションを別のアプリと同じドメインで実行していたが、別のポートを使用していたためです(mydomain.comが元のCookieを設定しました)バグのあるアプリがmydomain.com:123で実行されていたときに、明らかにChromeが間違ったCookieを送信したため、CSRF保護はトークンを正しいセッションにリンクできませんでした。
修正:問題のドメインのすべてのCookieをクリアし、ポートが異なる同じドメインで複数のアプリケーションを実行しないようにしてください。
私の場合、エンティティのmaxSizeアノテーションで問題が発生したため、2048から20048に増やしました。
/**
* @Assert\File(
* maxSize = "20048k",
* mimeTypes = {"application/pdf", "application/x-pdf"},
* mimeTypesMessage = "Please upload a valid PDF"
* )
*/
private $file;
この答えがお役に立てば幸いです!
フォームをプレーンHTMLからTwigに変換した場合は、</form>
終了タグを削除し忘れないようにしてください。愚かな間違いですが、私が発見したように、それはこの問題の考えられる原因です。
このエラーを受け取ったとき、最初はそれを理解できませんでした。 form_start()
とform_end()
を使用してフォームを生成しているので、tokenを明示的に追加する必要はありません。 form_row(form._token)
、またはform_rest()
を使用して取得します。 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>
明らかに、解決策は余分な終了タグを削除し、多分もう少しコーヒーを飲むことです。
同じエラーが発生しましたが、私の場合は、アプリケーションが複数の第1レベルドメインを使用しているのに、Cookieが1つのドメインを使用していたという問題がありました。 cookie_domain: ".%domain%"
のframework.session
からconfig.yml
を削除すると、Cookieがデフォルトでフォームが存在するドメインになり、問題が修正されました。
Form_rowまたはform_restを使用したくない場合に、twigテンプレートの_tokenの値にアクセスしたいだけです。以下を使用してください。
<input type="hidden" name="form[_token]" value="{{ form._token.vars.value }}" />