Ce qui se passe
Se déconnecter par un simple lien pose un problème de fond : navigateurs, robots d'aperçu de liens, scanners de sécurité et proxys d'entreprise suivent les liens d'eux-mêmes, et déconnectent l'utilisateur sans qu'il l'ait demandé. Symfony 8.2 apporte trois changements autour de la déconnexion, selon le billet de blog du projet.
1. Déconnexion en POST
La solution consiste à n'accepter que les requêtes POST sur la route de
déconnexion, ce qui impose un formulaire à la place du lien. Pour le construire :
- la fonction Twig
logout_form()renvoie l'action du formulaire et ses champs cachés, jeton CSRF compris si le pare-feu l'active ; elle accepte, commelogout_path(), le nom du pare-feu ; logout_button()rend directement le formulaire complet, y compris avec la protection CSRF sans état ;- côté PHP,
LogoutUrlGenerator::getLogoutForm()fait la même chose ; - l'usurpation d'identité suit le même principe avec
impersonation_button()etimpersonation_exit_button(); le second ne rend rien quand personne n'est usurpé.
Crédité à Nicolas Grekas.
2. Pas de redirection après la déconnexion
Avec une connexion JSON, on personnalisait la réponse de connexion dans un
contrôleur, mais pas celle de déconnexion sans écouteur d'événement. En 8.2,
logout.target à null supprime la redirection :
security:
firewalls:
main:
logout:
target: nullLa requête atteint alors le contrôleur de la route de déconnexion, qui construit sa propre réponse. Crédité à Jérôme Vasseur.
3. Déconnexion par canal arrière avec OpenID Connect
La connexion OpenID Connect, nouvelle en 8.2, gère le back-channel logout : quand l'utilisateur se déconnecte chez le fournisseur d'identité, celui-ci envoie à l'application un jeton de déconnexion signé. Symfony vérifie signature et revendications, range la session terminée dans un pool de cache, et déconnecte l'utilisateur à sa prochaine requête. Crédité à Florent Morselli.
Contraintes : cela ne fonctionne qu'avec des pare-feux à état, et le pool de
cache doit être partagé par tous les serveurs, sans éviction avant expiration.
L'URL de déconnexion se déclare comme backchannel_logout_uri du client chez le
fournisseur.
Comment s'y prendre
- Restreindre la route de déconnexion à
POSTet remplacer les liens parlogout_button(). - En API JSON, mettre
logout.targetànullet répondre depuis le contrôleur. - Avec OpenID Connect, déclarer l'URL de déconnexion chez le fournisseur et vérifier le pool de cache partagé.
Source : New in Symfony 8.2: Safer and More Flexible Logout, blog Symfony, 13 octobre 2026.