Hallo,
ich habe in den letzten Tagen an meiner Erweiterung für Isotope iso_productfeed weiter gearbeitet (Der main-branch ist der aktuelle Stand).
Ich habe darin die TC_Table erweitert um ein kleines Feedback-Kontaktformular zu integrieren. Ich habe alles soweit gut hinbekommen. Die Tokens sind identisch, aber ich bekomme trotzdem die Fehlermeldung:
Code:
Invalid CSRF token. Please reload the page and try again.
beim absenden.
Hat Jemand vielleicht das gleiche schonmal programmiert und kann mir da helfen. Ich weiß echt nicht, was da falsch läuft.
Warscheinlich muss man sich die Erweiterung installieren um den Code zu debuggn.
Ansonsten wären hier die zwei wichtigsten Klassen:
1.
Code:
<?php
namespace Bits\IsoProductfeed\Contao;
use Contao\DC_Table;
use Contao\System;
use Contao\Environment as ContaoEnvironment;
use Twig\Environment;
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Bits\IsoProductfeed\Form\FeedbackType;
class DC_IsoProductfeed extends DC_Table
{
protected $strTable = 'tl_iso_productfeed';
public function __construct($strTable)
{
parent::__construct($strTable);
}
public function showAll()
{
// Hole die aktuelle Request aus dem Symfony-Container
$request = System::getContainer()->get('request_stack')->getCurrentRequest();
return $this->generateForm($request) . parent::showAll();
}
private function processForm(array $data)
{
// Daten speichern oder verarbeiten
return 'Formular erfolgreich verarbeitet.';
}
public function generateForm($request)
{
// Formular erstellen
$container = System::getContainer();
$formFactory = $container->get('form.factory');
// Hole den CSRF-Token-Manager aus dem Container
$csrfTokenManager = System::getContainer()->get('security.csrf.token_manager');
$csrfToken = $csrfTokenManager->getToken('feedback_form')->getValue();
$form = $formFactory->create(FeedbackType::class, null, [
'action' => ContaoEnvironment::get('base').ContaoEnvironment::get('request'),
'csrf_token' => $csrfToken,
]);
//var_dump('1: '. $csrfToken);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$data = $form->getData();
return $this->processForm($data);
}
$twig = $container->get('twig');
return $twig->render('@Contao/iso_productfeed_panel.html.twig', [
'form' => $form->createView(),
]);
}
}
2.
Code:
<?php
namespace Bits\IsoProductfeed\Form;
use Contao\System;
use Bits\IsoProductfeed\Entity\Feedback;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
class FeedbackType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$container = System::getContainer();
$formFactory = $container->get('form.factory');
//var_dump('2: '.$options['csrf_token']);
$builder
->add('name')
->add('email')
->add('message')
->add('_token', HiddenType::class, [
'data' => $options['csrf_token'], // Möglichkeit, CSRF-Token als Option zu übergeben
])
->add('submit', SubmitType::class, [
'label' => 'Senden',
]);
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => Feedback::class,
'csrf_protection' => true,
'csrf_field_name' => '_token',
'csrf_token_id' => 'feedback_form',
'csrf_token' => Null
]);
}
}
Achso und die services.yaml:
Code:
# This file is the entry point to configure your own services.
# Files in the packages/ subdirectory configure your dependencies.
# Put parameters here that don't need to change on each machine where the app is deployed
# https://symfony.com/doc/current/best_practices.html#use-parameters-for-application-configuration
parameters: null
services:
# default configuration for services in *this* file
_defaults:
autowire: true # Automatically injects dependencies in your services.
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
Bits\IsoProductfeed\Contao\DC_IsoProductfeed:
arguments:
$twig: '@twig'
Symfony\Component\Security\Csrf\CsrfTokenManagerInterface: '@security.csrf.token_manager'
Bits\IsoProductfeed\EventListener\DataContainer\IsoProductfeedOnSaveListener:
tags: ['contao.callback']
Bits\IsoProductfeed\EventListener\DataContainer\IsoProductsOnSaveListener:
tags: ['contao.callback']
Symfony\Component\Form\FormFactoryInterface:
alias: 'form.factory'
# makes classes in src/ available to be used as services
# this creates a service per class whose id is the fully-qualified class name
Bits\IsoProductfeed\:
resource: ../../../src
exclude:
- ../../../src/{ContaoManager,DependencyInjection,Resources}
# - '../../../src/Backend/ConfigModule.php'
# - '../../../src/Eventlistener/'
Danke schonmal :-)