提交表单:The csrf token is invalid. Please try to resubmit the form
时,我在Symfony4中遇到此错误。
我尝试实现CSRF保护,因为我希望表单输入使用Bootstrap进行样式设置。
这是我的表格:
<?php
// src/Form/NewsType.php
namespace App\Form;
use App\Entity\News;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\OptionsResolver\OptionsResolver;
class NewsType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('image', NewsImageType::class, array('required' => false))
->add('content', TextareaType::class)
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => News::class,
// enable/disable CSRF protection for this form
'csrf_protection' => true,
// the name of the hidden HTML field that stores the token
'csrf_field_name' => '_token',
// an arbitrary string used to generate the value of the token
// using a different string for each form improves its security
'csrf_token_id' => 'publish-news',
));
}
}
framework.yaml:
framework:
secret: '%env(APP_SECRET)%'
#default_locale: en
csrf_protection: ~
#http_method_override: true
# uncomment this entire section to enable sessions
session:
# With this config, PHP's native session handling is used
handler_id: ~
#esi: ~
#fragments: ~
php_errors:
log: true
我的控制器:
namespace App\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Filesystem\Filesystem;
use App\Entity\News;
use App\Form\NewsType;
use App\Form\NewsType2;
/**
* @Route("/{_locale}/news", requirements={"_locale" = "fr|en"})
*/
class NewsController extends BackController
{
/**
* @Route("/", name="news")
*/
public function index(Request $request)
{
$this->initialize();
$repository = $this->getDoctrine()->getRepository(News::class);
$nbNews = $repository->getNbNews();
$news = new News();
$form = $this->createForm(NewsType::class, $news)
->add('save', SubmitType::class, array('label' => 'Publier'));
$form->handleRequest($request);
if ($form->isSubmitted() AND $form->isValid()) {
$submittedToken = $request->request->get('token');
// 'publish-news' is the same value used in the template to generate the token
if ($this->isCsrfTokenValid('publish-news', $submittedToken)) {
$news->setUser($this->getUser());
$news->setSharingUser($this->getUser());
$image = $news->getImage();
$em = $this->getDoctrine()->getManager();
if ($image != NULL) {
$em->persist($image);
}
$em->persist($news);
$em->flush();
return $this->redirectToRoute('news');
}
}
$this->addToTemplateArray(array(
'form' => $form->createView(),
'nb_news' => $nbNews,
'nav' => "news",
));
return $this->render('news/news.html.twig', $this->templateArray);
}
我的模板:
{# templates/blog/index.html.twig #}
{% extends 'base.html.twig' %}
{% block title %}{{ parent() }} | News{% endblock %}
{% block body %}
{% if is_granted('IS_AUTHENTICATED_FULLY') %}
<div class="news-form">
{{ form_start(form) }}
{#{{ form_label(form.content) }}#}
{{ form_errors(form.content) }}
{#{{ form_widget(form.content) }}#}
{{ form_errors(form.image) }}
{{ form_widget(form.image.image) }}
{#Joindre <a href="javascript:void(0);">une photo</a> |
<a href="javascript:void(0);">un album</a>#}
<div class="form-group">
<textarea class="form-control" id="news_content" name="news[content]" required="required"></textarea>
<button type="submit" id="news_save" name="news[save]">Publier</button>
</div>
<input type="hidden" name="_token" value="{{ csrf_token('publish-news') }}" />
{#{{ form_end(form) }}#}
</div>
{% else %}
<a href="{{ path('login') }}">{{ 'action.sign_in'|trans }}</a> pour pouvoir publier.
{% endif %}
<h3>{{ 'advert.nombre'|transchoice(nb_news) }} du monde</h3>
<div>
<a id="sort-date" href="javascript:void(0);">Sort by date</a> |
<a id="sort-sharings" href="javascript:void(0);">Sort by sharings</a> |
<a id="sort-comments" href="javascript:void(0);">Sort by comments</a>
</div>
<div id="news-list" style="text-align: center;">
<img src="{{ asset('images/ajax-loader.gif') }}"></img>
</div>
{% endblock %}
{% block javascripts %}
{{ parent() }}
<script src="{{ asset('build/js/news.js') }}"></script>
<script src="{{ asset('build/js/news_ready.js') }}"></script>
{% endblock %}
我不想使用{{ form_end(form) }}
。该如何解决?
我试图复制Symfony文档的How to Implement CSRF Protection
。但是我不明白为什么CSRF令牌有错误。