Bonjour à tous,

Je souhaite utiliser la protection csrf dans un appel ajax au click sur une image pour la supprimer, pour cela j'ai suivi un tuto en ligne, malheureusement la méthode 'DELETE' n'est pas acceptée et le $request->request->getContent() ou bien $request->request->getString('_token') retournent un null, que j' inclue la galerie d'image dans le form ou à l'extérieur...
Quelle serait la bonne méthode selon vous avec Symfony 7.1 et Ajax ?

Merci d'avance

GaleriesController.php :

#[Route('supprimer-image/{id}', 'supprimer_image',methods:['GET','DELETE'])]
    public function supprimerImage(Images $image, Request $request, EntityManagerInterface $em): Response
    {
        $request->enableHttpMethodParameterOverride();
        dd($request->request->getString('_token'));
        $data = json_decode($request->getContent(), true);
        if ($this->isCsrfTokenValid('delete' . $image->getId(), $data['_token'])) {
            $nom = $image->getName();
            unlink($this->getParameter('images_directory') . '/' . $nom);
            $em->remove($image);
            $em->flush();

            return new JsonResponse(['success' => 1]);
        } else {
            return new JsonResponse(['error' => 'Token invalide'], 400);
        }
    }

_galerie.html.twig :

{% for image in images %}
    <div class="miniature">

        <a class="btn-suppression-image" 
        href="{{path('galeries_supprimer_image',{'id':image.id})}}" 
        data-delete data-token="{{csrf_token('delete' ~ image.id)}}">&times;</a>
        <img src="{{asset('/uploads/images/mini/300x300-' ~ image.name)}}" alt="{{image.name}}" width="150">

_galeries.js :


window.onload = () => {
  //Supprimer une image
  const btnSuppression = document.querySelectorAll(["data-delete"]);

  for (btn of btnSuppression) {
    btn.addEventListener("click", (e) => {
      console.log("click sur suppression");
      e.preventDefault();
      if (confirm("Etes-vous sûr(e) de vouloir supprimer cette image ?")) {
        fetch(btn.getAttribute("href"), {
          method: "DELETE",
          headers: {
            "X-Requested-With": "XMLHttpRequest",
            "Content-Type": "application/json",
          },
          body: JSON.stringify({ _token: btn.dataset.token }),
        })
          .then((response) => response.json())
          .then((data) => {
            if (data.success) {
              btn.parentElement.remove();
            } else {
              alert(data.error);
            }
          })
          .catch((e) => alert(e));
      }
    });
  }
};

1 réponse


Salut,

Pour que ta méthode DELETE soit acceptée avec CSRF en Ajax, tu devrais essayer de passer ton token CSRF dans les headers de ta requête Ajax. Voici un exemple de ce à quoi ça pourrait ressembler en jQuery :

$.ajax({
    url: '/supprimer-image/' + imageId,
    type: 'DELETE',
    headers: {
        'X-CSRF-Token': csrfToken
    },
    success: function(response) {
        // Ton code pour gérer la réponse
    },
    Et dans ton contrôleur Symfony, assure-toi de récupérer le token depuis les headers :
    $csrfToken = $request->headers->get('X-CSRF-Token');
if ($this->isCsrfTokenValid('delete' . $image->getId(), $csrfToken)) {
    // Ton code pour supprimer l'image
}