Este foro ya no está activo, así que no puedes publicar nuevas preguntas ni responder a las preguntas existentes.

Cuál es la mejor forma de establecer variables de sesión en un service interactive_login

17 de febrero de 2015

Hola.

Necesito tomar algunas decisiones en mi aplicación respecto al usuario que se loguea.

Tengo este servicio:

login_listener:
    class: AppBundle\Listener\LoginListener
    arguments: [@security.authorization_checker, @security.token_storage, @router]
    tags:
        - { name: kernel.event_listener, event: security.interactive_login }
        - { name: kernel.event_listener, event: kernel.response }

Y esta es la clase LoginListener:

<?php
 
// src/AppBundle/Listener/LoginListener.php
namespace AppBundle\Listener;
 
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\Router;
 
class LoginListener
{
    private $router, $ciudad = null;
 
    public function __construct(Router $router)
    {
        $this->router = $router;
    }
 
    public function onSecurityInteractiveLogin(InteractiveLoginEvent $event)
    {
        $token = $event->getAuthenticationToken();
    }
 
    public function onKernelResponse(FilterResponseEvent $event)
    {
        if (...) {
            $event->setResponse(new RedirectResponse(...));
        }
    }
}

Debo hacer una serie de consultas a la base de datos (para lo cual pienso inyectar repositorios como servicios al servicio login_listener).

Una vez obtenido esos valores debo guardarlos en variables de sesión (si hay otra forma de almacenamiento sería bueno saberlo) los cuales voy a usar durante todo el tiempo que el usuario se mantenga conectado.

Yo se que el objeto que guarda las sesiones es el Request lo debo pasar como argumento al servicio y usarlo en el método onSecurityInteractiveLogin() o al inyectar ese servicio debo agregar un nuevo método?

Muchas gracias por su ayuda.


Respuestas

#1

En este caso no tienes que pasar el objeto que representa a la petición del usuario. El motivo es que la clase InteractiveLoginEvent (como la mayoría de eventos propios que proporciona Symfony) ya incluye dentro el objeto $request, por lo que puedes usarlo directamente así:

// src/AppBundle/Listener/LoginListener.php
namespace AppBundle\Listener;
 
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
 
class LoginListener
{
    // ...
 
    public function onSecurityInteractiveLogin(InteractiveLoginEvent $event)
    {
        $session = $event->getRequest()->getSession();
        $session->set('clave', 'valor');
    }
 
    // ...
}

@javiereguiluz

17 febrero 2015, 15:00
#2

Grandioso.

Muchas gracias por tu respuesta.

Voy a hacer más ladybug_dump_die($event); para ver qué hay por detrás.

Gracias.

@ramiroanacona

17 febrero 2015, 15:13
#3

Hola Javier.

Tengo una duda mas, sobre buenas practicas.

Quiero hacer un servicio que le provee funcionalidad a la aplicación (no responde a ningún evento), en que directorio debo guardar la clase que responde a este servicio?

Gracias.

@ramiroanacona

17 febrero 2015, 16:50
#4

La recomendación consiste en guardar los servicios en directorios con un nombre que los agrupe por funcionalidad: Mailer, Checker, etc. Si son servicios muy pequeños y no se te ocurre ningún nombre bueno, algunos programadores utilizan Utils o Services como nombre del directorio, pero no te aconsejo utilizar esos nombres porque son demasiado genéricos.

Una buena fuente de inspiración puede ser ver el código fuente de los mejores proyectos Symfony. Te indico a continuación tres referencias que consulto habitualmente para saber cómo organizan su código (entra dentro de los bundles de cada proyecto para ver cómo llaman a sus directorios y cómo organizan los servicios):

@javiereguiluz

17 febrero 2015, 17:24