2012-03-16 9 views
5

Nie mogę uwierzytelnić w symfony2 z jednostką "Pracownik", ponieważ zawiera wiele map z innymi podmioty w moim projekcie. niektóre z moich map są następujące:Wyjątek: Symfony Component Security Core Authentication Token UsernamePasswordToken :: serialize() musi zwracać ciąg znaków lub NULL

/** 
    * @var EmployeeDesignation 
    * 
    * @ORM\ManyToOne(targetEntity="EmployeeDesignation") 
    * @ORM\JoinColumns({ 
    * @ORM\JoinColumn(name="employee_designation_id", referencedColumnName="id") 
    * }) 
    */ 
    private $employeeDesignation; 

    /** 
    * @var EmployeeDesignation 
    * 
    * @ORM\ManyToOne(targetEntity="EmployeeType") 
    * @ORM\JoinColumns({ 
    * @ORM\JoinColumn(name="employee_type_id", referencedColumnName="id") 
    * }) 
    */ 
    private $employeeType; 

Uwierzytelnianie działa poprawnie bez żadnego mapowania. Próbowałem z 'Serialize()' i 'unserialize() metody w nim jak poniżej:

class Employee implements AdvancedUserInterface, \Serializable{ 
    /** 
      * serialize the username 
      * @return serialize 
      */ 
      public function serialize() { 
       return serialize($this->emailOfficial); 
      } 

      /** 
      * unserialize 
      * @param $data 
      */ 
      public function unserialize($data) { 
       $this->em = unserialize($data); 
      } 

otrzymuję następujący błąd po wykonaniu powyższej metody:

You cannot refresh a user from the EntityUserProvider that does not contain an identifier. The user object has to be serialized with its own identifier mapped by Doctrine. 

Próbowałem w ten sposób, aby pozbyć się poprzedniego błędu, który przedstawia się następująco:

Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken::serialize() must return a string or NULL 

więc może ktoś proszę sugerują sposób, aby przezwyciężyć ten problem?

Odpowiedz

19

Napotkałem coś podobnego, a po pewnych badaniach spróbowałem tego samego, co ty.

Ale w pewnym momencie dowiedziałem się, że ustawiając metodę __sleep, wszystko działa dobrze.

 
class User implements PlayerInterface 
{ 
    /** 
    * @var integer $id 
    * 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $id; 
... 

    public function __sleep() 
    { 
     return array('id'); 
    } 
... 
  • Upewnij się, że pole, które jest zdefiniowane jako @ORM\Id jest częścią zwróconej tablicy.
  • Upewnij się, że upuściłeś ciasteczko przeglądarki, ponieważ używa ono sesji.

Nie wiem dokładnie dlaczego powoduje to przy zakładaniu nowego stowarzyszenia (kopalnia była ManyToMany), ale prawdopodobnie pochodzi z tego miejsca:

 
// see Symfony\Component\Security\Http\Firewall\ContextListener::onKernelResponse() 
... 
     $event->getRequest() 
      ->getSession() 
      ->set('_security_'.$this->contextKey, serialize($token)); 
... 

Nadzieja to może komuś pomóc.

Edit:

Referencje:

+0

Dziękuję bardzo !!! Bardzo pomocne! – Ben

+0

oszczędziłeś mi wiele czasu na debugowanie, dziękuję –

+1

Myślę, że ten komunikat o błędzie pojawia się, gdy twoja encja użytkownika ma relację, która łączy się z użytkownikiem, np .: 'User-> Article-> Author' (' User' ma wiele 'artykułów 'i' Artykuł' ma 'User' jako autora), a następnie serializacja kończy się niepowodzeniem. Właśnie dlatego, gdy serializuje się 'Użytkownika' używając tylko klucza podstawowego (id) wszystkie rzeczy są wykonywane poprawnie. Tak więc użyj funkcji '__sleep' i zwróć klucz podstawowy. – Dmitriy

2

Dla mnie tylko to działało:

class User implements UserInterface

do

class User implements UserInterface, \Serializable

i musiałem dodać następujące metody do User Klasa:

public function serialize() { 
    return serialize($this->username); 
} 

public function unserialize($data) { 
    $this->username = unserialize($data); 
} 
0

Należy umieścić „chroniony” w każdej zmiennej klasy użytkownika. Przynajmniej dla mnie ta praca :)

Powiązane problemy