环顾四周后,我无法找到解决方法。我只是在提交通过Ajax时才会收到错误。这意味着我事先以常规的Symfony方式提交了表单而没有任何问题。
CSRF令牌无效。请尝试重新提交表单。
什么有效:
$形式 - >提交($请求 - >请求 - >获得($形式 - >的getName( '用户')));
根据要求,见
的输出的var_dump($请求 - >请求 - >获得($形式 - >的getName( '用户')));
array(8) {
["name"]=> string(9) "fafdffafa"
["avatar"]=> string(9) "dfafffafa"
["cityId"]=> string(1) "6"
["phone"]=> string(14) "33434343434344"
["email"]=> array(2) {
["first"]=> string(22) "myemail@gmail.com"
["second"]=> string(22) "myemail@gmail.com" }
["plainPassword"]=> array(2) {
["first"]=> string(8) "senha444"
["second"]=> string(8) "senha444" }
["blogSubs"]=> string(1) "1"
["_token"]=> string(43) "hLhyoRxVYmJ_FWK0FqXmiiEYZMZ77fDAWvxCZMXCtxw" }
只是为了确认如果我只是注释掉下面的javascript ,则提交将起作用并且实体将被保留。
这是相同的var_dump,这次是事情发生的时候。
array(9) {
["name"]=> string(12) "dfdfdfdfafaf"
["avatar"]=> string(13) "dfdfdfdafdafa"
["cityId"]=> string(1) "8"
["phone"]=> string(16) "3343434343343343"
["email"]=> array(2) {
["first"]=> string(22) "myemail@gmail.com"
["second"]=> string(22) "myemail@gmail.com" }
["plainPassword"]=> array(2) {
["first"]=> string(8) "senha444"
["second"]=> string(8) "senha444" }
["blogSubs"]=> string(1) "1"
["save"]=> string(0) ""
["_token"]=> string(43) "hLhyoRxVYmJ_FWK0FqXmiiEYZMZ77fDAWvxCZMXCtxw" }
这是Symfony生成的提交按钮,但不是由js序列化捕获的。
<button type="submit" id="user_save" name="user[save]" class="btn-default btn">Créer mon compte</button>
表单(我正在跳过表单$ builder,因为它似乎没必要)
应用程序/资源/视图/普通/ register.html.twig
{{ form_start(form, { 'attr': { 'id': 'signup_form' }}) }}
<div class="contact input-group">
{{ form_widget(form.name) }}
</div>
<div class="contact input-group">
{{ form_widget(form.avatar) }}
<span class="input-group-addon" id="info_avatar">
<i class="fa fa-info"></i>
</span>
</div>
<div class="contact input-group">
{{ form_widget(form.cityId) }}
</div>
<div class="contact input-group">
{{ form_widget(form.phone) }}
</div>
<div class="contact input-group">
{{ form_widget(form.email) }}
</div>
<div class="contact input-group">
{{ form_widget(form.plainPassword) }}
</div>
<div class="contact">
{{ form_widget(form.blogSubs) }}
</div>
<div class="contact form-group ">
{{ form_widget(form.save) }}
</div>
{{ form_end(form) }}
同一档案上的javascript:
<script>
$('body').on('submit','#signup_form',function(event) {
event.preventDefault();
var str = $("#signup_form").serialize();
$.ajax({
url: "/inscription",
type: "POST",
dataType:"json",
data: str,
success: function (data) {
alert(data);
}
});
});
</script>
控制器(在SO上找到了getErrorMessages()方法。)
/src/UsedBundle/Controller/RegistrationController.php
namespace UsedBundle\Controller;
use UsedBundle\Form\UserType;
use UsedBundle\Entity\User;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
class RegistrationController extends Controller
{
/**
* @Route("/inscription", name="inscription")
*/
public function registerAction(Request $request)
{
$user = new User();
$form = $this->createForm(UserType::class, $user);
if ($request->isMethod('POST')) {
var_dump($_POST);
$form->submit($request->request->get($form->getName('user')));
if(!$form->isValid()){
$errors = $this->getErrorMessages($form);
var_dump($errors);
}
if ($form->isSubmitted() && $form->isValid()) {
$password = $this->get('security.password_encoder')
->encodePassword($user, $user->getPlainPassword());
$user->setPassword($password);
$email = $user->getEmail();
$user->setUserKey( $email );
$user->setUserKeyTime();
$user->setDateReg();
$em = $this->getDoctrine()->getManager('used');
$em->persist($user);
$em->flush();
return new JsonResponse(array('message' => 'Success!'));
}
}else{
return $this->render(
'common/register.html.twig',
array('form' => $form->createView())
);
}
}
protected function getErrorMessages($form)
{
$errors = array();
foreach ($form->getErrors() as $key => $error) {
$errors[] = $error->getMessage();
}
foreach ($form->all() as $child) {
if (!$child->isValid()) {
$errors[$child->getName()] = $this->getErrorMessages($child);
}
}
return $errors;
}
}
答案 0 :(得分:1)
正如评论中所讨论的,您的问题的原因与不同的环境有关。如果您使用带有app_dev.php
前端控制器的标准Symfony项目,则表单将使用dev
环境的有效csrf标记进行呈现。您的JavaScript代码
$.ajax({
url: "/inscription",
type: "POST",
dataType:"json",
data: str,
success: function (data) {
alert(data);
}
});
不知道Symfony环境,因此url /location
指向prod
环境,导致CSRF令牌无效的错误消息。
要解决此问题,您可以让您的前端代码了解Symfony路由,例如使用FOSJsRoutingBundle。或者,您可以为dev
环境禁用CSRF保护:
# app/config/config_dev.yml
framework:
csrf_protection: false