Redirection dynamique avec un formulaire de connexion traditionnel Symfony
Si vous utilisez un formulaire de connexion traditionnel et que vous voulez rediriger de manière dynamique l'utilisateur vers une page précise, il existe le paramètre de configuration success_handler du composant de sécurité. Ce paramètre de configuration est très peu documenté. Je vais donner ici un exemple d'utilisation.
Contexte
Il existe différentes méthodes pour rediriger vers une page après une connexion réussie. Cependant, il est nécessaire de connaitre à l'avance la page cible. Si vous avez des règles métiers complexes, par exemple vous devez rediriger vers différents endroits en fonction de l'utilisateur qui s'est connecté, le paramétre de configuration success_handler peut répondre à votre besoin.
Pour illustrer le propos, je vais prendre un exemple simple. En fonction des préférences de l'utilisateur, on doit rediriger cet utilisateur vers la bonne page d'accueil et la bonne locale après une connexion réussie.
Solution
Il va être nécessaire de créer un service qui implémente Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface. On va nommer ce service AuthentificationSuccessHandler. Avant de le créer, on va configurer le composant sécurité (fichier security.yml) pour lui demander d'appeler ce service, en cas de connexion réussie. Comme vu en introduction, c'est grâce au paramètre success_handler :
security:
firewalls:
main:
form_login:
success_handler: App\Security\Handler\AuthentificationSuccessHandler
Ensuite, on crée notre service AuthentificationSuccessHandler :
<?php
namespace App\Security\Handler;
use App\Entity\Collaborator;
use App\Cms\HomepageFinder;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
class AuthentificationSuccessHandler implements AuthenticationSuccessHandlerInterface
{
/** @var RouterInterface */
private $router;
/** @var HomepageFinder */
private $homepageFinder;
/**
* LogoutSuccessHandler constructor.
*
* @param HomepageFinder $homepageFinder
* @param RouterInterface $router
*/
public function __construct(HomepageFinder $homepageFinder, RouterInterface $router)
{
$this->router = $router;
$this->homepageFinder = $homepageFinder;
}
/**
* {@inheritdoc}
*/
public function onAuthenticationSuccess(Request $request, TokenInterface $token)
{
/** @var Collaborator $collaborator */
$collaborator = $token->getUser();
$targetRouteName = $this->homepageFinder->getHomepageRoute($collaborator->getEmployer());
return new RedirectResponse($this->router->generate($targetRouteName, [
'_locale' => $collaborator->getLocale(),
]));
}
}
L'interface AuthenticationSuccessHandlerInterface nécessite d'implémenter la méthode onAuthenticationSuccess.
Elle donne accès à la requête en cours et au token de l'utilisateur qui vient de se connecter.
Si vous avez besoin d'autres services, il suffit de les injecter dans le constructeur. Par exemple, ici on a service qui retourne le nom de la route cible en fonction de l'utilisateur connecté.
La méthode onAuthenticationSuccess doit retourner une réponse. Ici on redirige vers la page d'accueil destinée à cet utilisateur, grâce au service HomepageFinder.
Version
Cet article a été testé avec :
Symfony : >= 3.4
PHP : >= 7.1