2013-02-14 6 views
5

To pytanie o Symfony 2.1Jak korzystać z fabryki koderów w Symfony 2 wewnątrz setera modelowania?

Jak mogę zakodować hasło użytkownika z:

$factory = $this->get('security.encoder_factory'); 
$user = new Acme\UserBundle\Entity\User(); 

$encoder = $factory->getEncoder($user); 
$password = $encoder->encodePassword('ryanpass', $user->getSalt()); 
$user->setPassword($password); 

i podstawa config:

# app/config/security.yml 
security: 
    # ... 

    encoders: 
     Acme\UserBundle\Entity\User: sha512 

Wewnątrz modeli setter:

class User implements UserInterface, \Serializable 
{ 
    public function setPassword($password) 
    { 
     $this->password = $password; 
    } 
} 

I wierzysz, że proces szyfrowania hasła musi zajmować się mo del. Jak mogę korzystać ze standardowej fabryki koderów wewnątrz modelu?

Odpowiedz

3

Jednostka zawiera dane, a nie obsługuje. Jeśli chcesz zmienić dane obiektu, możesz utworzyć detektor zdarzeń i zrobić rzeczy przed utrwaleniem. Sprawdź How to Register Event Listeners and Subscribers w oficjalnej dokumentacji.

Możesz również zapoznać się z FosUserBundle i zarządzaniem użytkownikami.

FosUserBundle UserManager

Tak, główną ideą jest przeniesienie zwykłego hasło z formularza do jednostki użytkownika i zakodować go przed persitence użyciu detektora zdarzeń.

+0

Tak, podmioty mogą również przetwarzać dane. Na przykład możesz dodać ROLĘ do użytkownika, który nie ma żadnej metody gettera, jak wyjaśniono tutaj: https://knpuniversity.com/screencast/symfony-security/dynamic-roles Nie wstawiłbym wszystkiego do encji, ale ustawiasz hasło i taka jest funkcja, więc moim zdaniem ma to sens. –

10

Chociaż zgadzam się z @Vadim, że nie powinno być nieszczelne logikę biznesową w modelu, byłbym ostrożny z odroczenia wycieniowanie tekstu jawnego hasła do imprezy prePersist, na przykład, jeśli nie nazwać persist i flush prawo po setPassword. W międzyczasie wywołanie getPassword zwróci ciąg tekstowy, chyba że zapisałeś go w osobnym polu, co może mieć poważne konsekwencje. Idealnie hasło w postaci zwykłego tekstu powinno istnieć tak krótko, jak to możliwe w cyklu życia aplikacji.

Polecam stosując warstwę serwisem w którym „User Manager” zapewnia interfejs do typowych zadań, tak że nie trzeba zanieczyszczają aĹ hasło nawet tymczasowo:

class UserManager 
{ 
    // ... 
    public function __construct(EncoderFactoryInterface $encoderFactory) 
    { 
     // $encoderFactory is injected by the DIC as requested by your service configuration 
     // ... 
    } 

    public function setUserPassword(UserInterface $user, $plaintextPassword) 
    { 
     $hash = $this->encoderFactory->getEncoder($user)->encodePassword($plaintextPassword, null); 
     $user->setPassword($hash); 
    } 
    // ... 
} 

W kontrolerze o rejestrację przesłanie formularza, na przykład:

public function userRegistrationAction() 
{ 
    // ... 
    if ($form->isValid()) { 
     $user = new User(); 
     // ... 
     $this->get('my.bundle.user_manager')->setUserPassword($user, $form->get('password')->getData()); 
     // ... 
    } 
}