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

Problemas al loguear usuarios de la aplicación CUPON (Symfony 2.3)

25 de agosto de 2014

Cuando intento loguear un usuario ya sea desde cajaLogin o desde Login me da este NOTICE:

ContextErrorException:
Notice: serialize(): "id" returned as member variable from __sleep()
but does not exist in D:\Cupon_Symfony\vendor\symfony\symfony\src\Symfony\Component\
Security\Core\Authentication\Token\AbstractToken.php line 159

NOTA: Al fijarme el barra de direcciones del navegador, veo que el error es generado en una de las direcciones que el framework se encarga de gestionar (login_check). Estas son las configuraciones de seguridad

security:
    firewalls:
        frontend:
            pattern:    ^/*
            anonymous:  ~
            form_login: 
                login_path: usuario_login
                check_path: usuario_login_check
            logout:
                path: usuario_logout
                target: /sitio/vuelve-pronto
            remember_me:
                key:    cupon1234
                lifetime: 3600
  access_control: - { path: ^/usuario/login, roles: IS_AUTHENTICATED_ANONYMOUSLY } - { path: ^/usuario/registro, roles: IS_AUTHENTICATED_ANONYMOUSLY } - { path: ^/usuario/*, roles: ROLE_USUARIO }   providers: usuarios: entity: { class: Cupon\UsuarioBundle\Entity\Usuario, property: email }   encoders: Cupon\UsuarioBundle\Entity\Usuario: {algorithm: sha512, iterations: 10}

Este es el routing del bundle Usuario

usuario_compra:
    path:  /compras
    defaults: { _controller: UsuarioBundle:Default:compras }
 
usuario_login:
    path:  /login
    defaults: { _controller: UsuarioBundle:Default:login }
 
usuario_login_check:
    path:  /login_check
 
usuario_logout:
    path:  /logout
 
usuario_registro:
    path:  /registro
    defaults: { _controller: UsuarioBundle:Default:registro }

Gracias de antemano


Respuestas

#1

¿La propiedad id de tu entidad User es de tipo private? En caso afirmativo, cámbiala por protected y prueba a ver si desaparece el error. Al parecer se trata de un error combinado de PHP y Doctrine al serializar propiedades privadas.

@javiereguiluz

25 agosto 2014, 19:50
#2

Hola @javiereguiluz: El error persiste. He cambiado a protegido el atributo privado id y sigue dando el mismo error en la misma clase. Lo cual me obliga a devolverlo a su atributo private, como debe ser. Trasteando y por error, me percato que en el entorno de producción esto no sucede, todo fluye con normalidad. Sin embargo en el entorno de desarrollo continúa saliendo. ¿Alguna otra idea del porqué de este error?

@jjaleman05

25 agosto 2014, 22:49
#3

En este artículo del blog de Asier Marqués he encontrado el siguiente comentario al respecto del error que se te produce:

The error appears when you have a Doctrine Entity implementing the UserInterface with a relation mapped in it.

Y la solución que plantea es implementar el método mágico __sleep() en la clase del usuario. Ejemplo:

use Symfony\Component\Security\Core\User\UserInterface;
 
class Usuario implements UserInterface
{
    // ...
 
    public function __sleep(){
        return array('id', 'username', 'email');
    }
}

@javiereguiluz

26 agosto 2014, 20:25
#4

Gracias @javiereguiluz, la solución que dio Asier Marqués, resuelve el problema, solo que hay que devolver el arreglo con el id solamente, al parecer su solución está dada por otras funcionalidades o acciones que se realizan con los demás atributos, pero bueno es buena esta solución. Saludos

@jjaleman05

29 agosto 2014, 17:40
#5

Perdón que me meta en el tema pero en mi proyecto (en Cupon no lo intente) la solución del __sleep(), no me solucionó del todo y busqué y encontré este artículo en la página oficial de Symfony.

/**
     * @see \Serializable::serialize()
     */
    public function serialize()
    {
        return serialize(array(
            $this->id,
            $this->username,
            $this->password,
            // see section on salt below
            // $this->salt,
        ));
    }
 
    /**
     * @see \Serializable::unserialize()
     */
    public function unserialize($serialized)
    {
        list (
            $this->id,
            $this->username,
            $this->password,
            // see section on salt below
            // $this->salt
        ) = unserialize($serialized);
    }

@AjPZZO

3 septiembre 2014, 4:42
#6

@AjPZZO muchas gracias por la referencia. Tienes toda la razón y probablemente sea mejor implementar la interfaz Serializable en vez de definir los métodos mágicos __sleep() y __wakeup(). En realidad Serializable llama a esos dos métodos, pero la primera es mejor porque por ejemplo no tiene problemas con propiedades privadas, tal y como se explica en el manual oficial de PHP.

@javiereguiluz

3 septiembre 2014, 8:41
#7

@javiereguiluz una vez q se cambien los atributos a protected ya no hay necesidad de usar la inteface \Serializable en el ejemplo cupon el id de cualquier entidad es integer y por eso no genera problema al rebuscar el usuario en la redireccion pero en mi aplicacion mi clase Usuario tiene en su id un objeto Persona y cuando quiere rebuscar el Usuario aparece el siguiente error:

// código PHP
Catchable Fatal Error: Object of class Proxies\__CG__\LaTorres\UsuarioBundle\Entity\Persona could not be converted to string in C:\xampp\htdocs\latorres\vendor\doctrine\orm\lib\Doctrine\ORM\UnitOfWork.php line 2791

El objeto Persona esta guardado como id en mi Usuario logeado, pero cuando automaticamente hace la consulta q esta en la linea indicada en el stack trace obviamente no obtiene nada y carga el usuario anonimo..

DEBUG - Notified event "kernel.request" to listener "Symfony\Component\Security\Http\Firewall::onKernelRequest". 
DEBUG - Read SecurityContext from the session 
DEBUG - Reloading user from user provider. 
----->DEBUG - SELECT t0.tipo AS tipo1, t0.username AS username2, t0.password AS password3, t0.id_persona AS id_persona4 FROM usuario t0 WHERE t0.id_persona = ? 
WARNING - Username "mono" could not be found. 
INFO - Populated SecurityContext with an anonymous Token 
DEBUG - Notified event "kernel.request" to listener "Symfony\Bundle\AsseticBundle\EventListener\RequestListener::onKernelRequest". 
DEBUG - Notified event "kernel.controller" to listener "Symfony\Bundle\FrameworkBundle\DataCollector\RouterDataCollector::onKernelController".

y esta es la dql que se envia a la BD

SELECT t0.tipo AS tipo1, t0.username AS username2, t0.password AS password3, t0.id_persona AS id_persona4 FROM usuario t0 WHERE t0.id_persona = 'Object(Proxies\\__CG__\\LaTorres\\UsuarioBundle\\Entity\\Persona)'
Parameters: [Object(Proxies\__CG__\LaTorres\UsuarioBundle\Entity\Persona)]

como ves el objeto persona se inserta como id, como puedo especificar que quiero enviar el id de la Persona y no el objeto para evitar perder el usuario que tengo logueado? Gracias por la ayuda que me puedan brindar

@mono_arevalo

30 septiembre 2014, 21:02