php CSRF 令牌无效。请尝试重新提交表格
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23455780/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
The CSRF token is invalid. Please try to resubmit the form
提问by Francisco Albert
I'm getting this error message every time I try to submit the form:
每次尝试提交表单时,我都会收到此错误消息:
The CSRF token is invalid. Please try to resubmit the form
CSRF 令牌无效。请尝试重新提交表格
My form code is this:
我的表单代码是这样的:
<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>
Any ideas?
有任何想法吗?
回答by M Khalid Junaid
You need to add the _token
in your form i.e
您需要_token
在表单中添加
{{ form_row(form._token) }}
As of now your form is missing the CSRF token field. If you use the twig form functions to render your form like form(form)
this will automatically render the CSRF token field for you, but your code shows you are rendering your form with raw HTML like <form></form>
, so you have to manually render the field.
截至目前,您的表单缺少 CSRF 令牌字段。如果您使用 twig 表单函数来呈现您的表单,这样form(form)
将自动为您呈现 CSRF 令牌字段,但您的代码显示您正在使用原始 HTML 呈现表单,例如<form></form>
,因此您必须手动呈现该字段。
Or, simply add {{ form_rest(form) }}
before the closing tag of the form.
或者,只需{{ form_rest(form) }}
在表单的结束标记之前添加。
According to docs
This renders all fields that have not yet been rendered for the given form. It's a good idea to always have this somewhere inside your form as it'll render hidden fields for you and make any fields you forgot to render more obvious (since it'll render the field for you).
根据文档
这将呈现尚未为给定表单呈现的所有字段。始终将它放在表单中的某个地方是个好主意,因为它会为您呈现隐藏字段并使您忘记呈现的任何字段更加明显(因为它会为您呈现该字段)。
回答by zalex
Also you can see this error message when your form has a lot of elements.
当您的表单有很多元素时,您也可以看到此错误消息。
This option in php.ini cause of problem
php.ini 中的这个选项导致问题
; How many GET/POST/COOKIE input variables may be accepted
max_input_vars = 1000
Problem is that _token field misses PUT (GET) request, so you have to increase value.
问题是 _token 字段未命中 PUT (GET) 请求,因此您必须增加值。
Also, it concerns a big files. Increasing the
此外,它涉及一个大文件。增加
upload_max_filesize
option will solve problem.
选项将解决问题。
回答by zalex
This happens because forms by default contain CSRF protection, which is not necessary in some cases.
发生这种情况是因为表单默认包含 CSRF 保护,这在某些情况下是不必要的。
You can disable this CSRF protection in your form class in getDefaultOptions
method like this:
您可以在表单类中禁用此 CSRF 保护,getDefaultOptions
方法如下:
// Other methods omitted
public function getDefaultOptions(array $options)
{
return array(
'csrf_protection' => false,
// Rest of options omitted
);
}
If you don't want to disable CSRF protection, then you need to render the CSRF protecion field in your form. It can be done by using {{ form_rest(form) }}
in your view file, like this:
如果您不想禁用 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) }}
renders all fields which you haven't entered manually.
{{ form_rest(form) }}
呈现您尚未手动输入的所有字段。
回答by Lkopo
Before your </form>
tag put:
在您的</form>
标签放置之前:
{{ form_rest(form) }}
It will automatically insert other important (hidden) inputs.
它会自动插入其他重要的(隐藏的)输入。
回答by Benoit Duffez
I had this issue with a weird behavior: clearing the browser cache didn't fix it but clearing the cookies (that is, the PHP session ID cookie) did solve the issue.
我遇到了一个奇怪行为的问题:清除浏览器缓存并没有解决它,但清除 cookie(即 PHP 会话 ID cookie)确实解决了这个问题。
This has to be done afteryou have checked all other answers, including verifying you dohave the token in a hidden form input field.
这必须完成后,你已经检查了所有其他的答案,包括验证你做有一个隐藏的表单输入字段令牌。
回答by Henry
In addition to others' suggestions you can get CSRF token errors if your session storage is not working.
除了其他人的建议之外,如果您的会话存储不工作,您可能会收到 CSRF 令牌错误。
In a recent case a colleague of mine changed 'session_prefix' to a value that had a space in it.
在最近的一个案例中,我的一位同事将“session_prefix”更改为一个包含空格的值。
session_prefix: 'My Website'
This broke session storage, which in turn meant my form could not obtain the CSRF token from the session.
这破坏了会话存储,这反过来意味着我的表单无法从会话中获取 CSRF 令牌。
回答by Michael
I had this error recently. Turns out that my cookie settings were incorrect in config.yml. Adding the cookie_path
and cookie_domain
settings to framework.session
fixed it.
我最近有这个错误。原来我的 cookie 设置在 config.yml 中不正确。添加cookie_path
和cookie_domain
设置来framework.session
修复它。
回答by Teo.sk
I hade the same issue recently, and my case was something that's not mentioned here yet:
我最近遇到了同样的问题,我的案例在这里还没有提到:
The problem was I was testing it on localhost
domain. I'm not sure why exactly was this an issue, but it started to work after I added a host name alias for localhost
into /etc/hosts
like this:
问题是我在localhost
域上测试它。我不知道到底为什么是这样一个问题,但它开始工作后,我添加了一个主机名别名localhost
到/etc/hosts
这样的:
127.0.0.1 foobar
There's probably something wrong with the session while using Apache and localhost
as a domain. If anyone can elaborate in the comments I'd be happy to edit this answer to include more details.
使用 Apache 和localhost
作为域时会话可能有问题。如果有人可以在评论中详细说明,我很乐意编辑此答案以包含更多详细信息。
回答by Don't Panic
If you have converted your form from plain HTML to twig, be sure you didn't miss deleting a closing </form>
tag. Silly mistake, but as I discovered it's a possible cause for this problem.
如果您已将表单从纯 HTML 转换为 twig,请确保您没有遗漏删除结束</form>
标记。愚蠢的错误,但正如我发现的那样,这可能是导致此问题的原因。
When I got this error, I couldn't figure it out at first. I'm using form_start()
and form_end()
to generate the form, so I shouldn't have to explicitly add the tokenwith form_row(form._token)
, or use form_rest()
to get it. It should have already been added automatically by form_end()
.
当我遇到这个错误时,一开始我无法弄清楚。我正在使用form_start()
和form_end()
来生成表单,所以我不必显式地添加令牌withform_row(form._token)
或 useform_rest()
来获取它。它应该已经由 自动添加form_end()
。
The problem was, the view I was working with was one that I had converted from plain HTML to twig, and I had missed deleting the closing </form>
tag, so instead of :
问题是,我正在使用的视图是我从纯 HTML 转换为 twig 的视图,并且我错过了删除结束</form>
标记,所以不是:
{{ form_end(form) }}
I had:
我有:
</form>
{{ form_end(form) }}
That actually seems like something that might throw an error, but apparently it doesn't, so when form_end()
outputs form_rest()
, the form is already closed. The actual generated page source of the form was like this:
这实际上看起来可能会引发错误,但显然不会,因此当form_end()
输出时form_rest()
,表单已经关闭。表单实际生成的页面源码是这样的:
<form>
<!-- all my form fields... -->
</form>
<input type="hidden" id="item__token" name="item[_token]" value="SQAOs1xIAL8REI0evGMjOsatLbo6uDzqBjVFfyD0PE4" />
</form>
Obviously the solution is to delete the extra closing tag and maybe drink some more coffee.
显然,解决方案是删除多余的结束标签,然后再喝一些咖啡。
回答by lkoell
I faced a similar issue. After ensuring the token field was actually rendered (see accepted answer) I checked my cookies. There were 2(!) cookies for the domain in my Chrome browser, apparently because I was running the application on the same domain as another app, but with a different port (i.e. mydomain.com set the original cookie while the buggy app was running on mydomain.com:123) Now apparently Chrome sent the wrong cookie so the CSRF protection was unable to link the token to the correct session.
我遇到了类似的问题。在确保实际呈现令牌字段后(请参阅接受的答案),我检查了我的 cookie。我的 Chrome 浏览器中有 2(!)个域的 cookie,显然是因为我在与另一个应用程序相同的域上运行该应用程序,但使用不同的端口(即 mydomain.com 在有问题的应用程序运行时设置了原始 cookie在 mydomain.com:123) 现在显然 Chrome 发送了错误的 cookie,因此 CSRF 保护无法将令牌链接到正确的会话。
Fix: clear all the cookies for the domain in question, make sure you don't run multiple applications on the same domain with differing ports.
修复:清除相关域的所有 cookie,确保您没有在具有不同端口的同一域上运行多个应用程序。