Aprende a implementar un detector de inicio de sesión que redirige a un usuario automáticamente a una ruta específica de acuerdo con su rol.

Cómo redirigir a un usuario a una página específica de acuerdo con su rol en Symfony 2.8 usando un EventListener

Aunque existen métodos más simples para redirigir a un usuario a una página específica de acuerdo con su rol en su aplicación basada en Symfony 2 con FOSUserBundle, como manejar tal cosa en alguna acción de un controlador de su aplicación:

<?php

/**
 * Redirigir a los usuarios después de iniciar sesión según el ROL concedido
 * @Route("/login/redirect", name="_login_redirect")
 */
public function loginRedirectAction(Request $request)
{
    if($this->isGranted('ROLE_ADMIN'))
    {
        return $this->redirectToRoute('admin_homepage');
    }
    else if($this->isGranted('ROLE_MANAGER'))
    {
        return $this->redirectToRoute('manager_homepage');
    }
    else
    {
        return $this->redirectToRoute('default_homepage');
    }
}

Hay desarrolladores a los que les encanta hacer las cosas un poco más complejas, aunque estén bastante estructuradas (como implementar el oyente de inicio de sesión). En este artículo, compartiremos con usted la forma más sencilla de implementar un detector de inicio de sesión que redirija al usuario registrado a un usuario específico de acuerdo con su función.

1. Cree un escucha de inicio de sesión

Lo primero que debe hacer es crear la clase LoginListener que manejará la redirección de acuerdo con el rol del usuario, generalmente creamos un directorio dentro de nuestro paquete principal, a saber, Listeners y guardamos todas las clases de oyentes dentro. Entonces el espacio de nombres de la clase será AppBundle\Listeners. El contenido de la clase es el siguiente:

<?php 

// Cambie el espacio de nombres de acuerdo con la ubicación de esta clase en su paquete
namespace AppBundle\Listeners;

use FOS\UserBundle\Model\UserManagerInterface;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\Routing\Router;
use Symfony\Component\Security\Core\SecurityContext;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpFoundation\RedirectResponse;

class LoginListener
{
    protected $userManager;
    protected $router;
    protected $security;
    protected $dispatcher;
    
    public function __construct(UserManagerInterface $userManager, Router $router, SecurityContext $security, EventDispatcher $dispatcher)
    {
        $this->userManager = $userManager;
        $this->router = $router;
        $this->security = $security;
        $this->dispatcher = $dispatcher;
    }
    
    public function onSecurityInteractiveLogin(InteractiveLoginEvent $event)
    {
        $this->dispatcher->addListener(KernelEvents::RESPONSE, array($this, 'onKernelResponse'));
    }
    
    public function onKernelResponse(FilterResponseEvent $event)
    {
        // Importante: redireccionar según el rol del usuario
        if ($this->security->isGranted('ROLE_ADMIN')) {
            $event->setResponse(new RedirectResponse($this->router->generate("admin_homepage")));
        } elseif ($this->security->isGranted('ROLE_MANAGER')) {
            $event->setResponse(new RedirectResponse($this->router->generate("manager_homepage")));
        } else {
            $event->setResponse(new RedirectResponse($this->router->generate("default_homepage")));
        }  
    }
}

El oyente esperará 4 argumentos que inyectaremos más adelante durante el registro del oyente. El primer argumento es el administrador de usuarios que ha registrado para su aplicación, en nuestro caso usamos FOSUserBundle.

2. Registrar oyente de inicio de sesión

Después de crear la clase y modificar las rutas de redireccionamiento de acuerdo con el rol del usuario firmado, debe registrar esta clase en el services.ymlarchivo de su proyecto con el siguiente fragmento (tenga en cuenta que la clase puede cambiar de acuerdo con la estructura de archivos y espacios de nombres que usted sigue):

# app/config/services.yml
services:     
    login_listener:
        # ruta de la clase creada anteriormente
        class:  AppBundle\Listeners\LoginListener
        arguments:
            userManager: "@fos_user.user_manager"
            router: "@router"
            security: "@security.context"
            dispatcher: "@event_dispatcher"
        tags:
            - { name: kernel.event_listener, event: security.interactive_login, method: onSecurityInteractiveLogin }

Guarda los cambios y limpia la caché de tu Symfony con  php app/console cache:clear y accede a tu aplicación, según el rol del usuario.

Que te diviertas ❤️!


Ingeniero de Software Senior en EPAM Anywhere. Interesado en la programación desde los 14 años, Carlos es un programador autodidacta, fundador y autor de la mayoría de los artículos de Our Code World.

Conviertete en un programador más sociable

Patrocinadores