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

Acceso a sesión y a EntityManager tras login

7 de julio de 2015

Hola! Estoy desarrollando un portal web con symfony2. Uso un LoginListener similar al del libro para redirigir tras el login.

Ahora estoy investigando cómo inyectar para poder acceder desde el LoginListener a la sesión y al EntityManager. El entityManager veo que es añadiendo @doctrine.orm.entity_manager como argumento en services. Pero para el acceso a la sesión no lo tengo claro.

Lo que quiero es guardar en la sesión un objeto que necesito consultar de la base de datos, para no tener que hacer la consulta a la base de datos siempre al principio de cada petición.

Concretamente, un centro logueado siempre tendrá un programa de intercambio de libros actual. Y ése es el que quiero que se mantenga en la sesión.

Y una pregunta más técnica: hay algún problema de seguridad en los datos de sesión? Me refiero a si debo comprobar que ese programa efectivamente pertenece al centro logueado cada vez que lo recupere de la sesión entre peticiones. Me imagino que no, que es un dato bien seguro. Pero sería catastrófico que un usuario usara un programa que no es suyo... lo cual me lleva a los voters que lo dejo para otra duda.


Respuestas

#1

Hola de nuevo, ya lo he solucionado usando:

services:
    login_listener:
        class:  redint\FrontendBundle\Listener\LoginListener
        arguments: [@doctrine.orm.entity_manager, @session,  ...]

Y en la clase LoginManager:

use Symfony\Component\HttpFoundation\Session\Session;
use Doctrine\ORM\EntityManager;

y recibo en el constructor:

public function __construct(EntityManager $em, Session $session, [...])

Así que perfecto.

Aunque no entiendo por qué en el profiler, al ver la sesión en uso, aparece el objeto programa que tengo en la sesión como:

Key     Value
programa    {}

De todas formas me gustaría pedir consejo si esto es una práctica deseable y:

  1. puedo confiar en que ese objeto que guardo en la sesión es seguro
  2. debo asegurarme que pertenece al usuario verificándolo en la base de datos.
  3. o si debo crear un voter para que quede más claro.

El tema de los voters no me queda claro cuándo conviene usarlos. Yo hasta ahora lo soluciono todo con consultas directas a la base de datos en los repositorios de entidad. Vamos que si las consultas están bien hechas, es seguro.

Supongo que los voters se deben orientar a comprobaciones típicas como: recibir un $id desde la url, y hacer una acción con ello. Yo hasta ahora cojo el URL, hago consulta y compruebo si hay resultado. Supongo que con un voter queda más escalable.

Un saludo.

@nando_sosa

7 julio 2015, 13:37
#2

Otra forma de hacer lo que quieres es usar un "login success handler, que es una clase que se ejecuta después de que el login del usuario se exitoso. En esa clase puedes hacer cualquier cosa y puedes inyectar cualquier servicio (como el entity manager y el session). Para configurar este handler solo tienes que añadir la opción success_handler en tu formulario de login*:

# app/config/security.yml
firewalls:
    main:
        pattern: ...
        form_login:
            success_handler: app.login_handler

En cualquier caso, todo lo anterior es opcional y puedes seguir usando el listener clásico.

Respecto a los voters, no es que siempre sean mejores, pero tienen muchas ventajas. La principal es que centralizan toda la lógica relacionada con la seguridad de acceso. La segunda ventaja es que tu código queda mucho más limpio, ya que sólo tienes que usar el método isGranted() y todos los voters adecuados se aplicarán para decidir si se permite el acceso o no.

De todas formas, si la aplicación te funciona bien y te sientes cómodo programando de esa manera, yo no lo cambiaría. Es mejor dedicar el tiempo a crear funcionalidades que dan valor a los usuarios y mejorar el código con cosas útiles como tests. Todo lo demás siempre puede esperar.

@javiereguiluz

8 julio 2015, 9:07
#3

Hola, este ejemplo de redirigir cuando se está haciendo login es un buen ejemplo. Quizás te ayude bastante.

Saludos!

@cristian_angulo

8 julio 2015, 16:01
#4

Hola, yo tengo un problema muy particular, implementé el success_handler y este me funciona perfecto en el entorno de desarrollo "app-dev.php", pero en el entorno de producción no funciona, alguna idea?

@LeonardoVizcaya

1 octubre 2015, 21:12