2013-10-31 9 views
13

powiedzmy na przykład ja przyznać nową rolę do aktualnie uwierzytelnionego użytkownika w sterowniku, tak:Symfony 2.3: Jak odświeżyć uwierzytelnionego użytkownika z bazy danych?

$em = $this->getDoctrine()->getManager(); 
$loggedInUser = $this->get('security.context')->getToken()->getUser(); 
$loggedInUser->addRole('ROLE_XYZ'); 

$em->persist($loggedInUser); 
$em->flush(); 

na następnej stronie obciążenia, kiedy chwycić uwierzytelniony użytkownik ponownie:

$loggedInUser = $this->get('security.context')->getToken()->getUser(); 

Nie dostają tej roli. Zgaduję, ponieważ dzieje się tak dlatego, że użytkownik jest przechowywany w sesji i musi zostać odświeżony.

Jak to zrobić?

Używam FOSUserBundle, jeśli to robi różnicę.

+0

Czy baza danych jest zaktualizowana? – cheesemacfly

+0

Tak, baza danych jest aktualizowana. Więc jeśli wyloguję się i ponownie, nowa rola zostanie odzwierciedlona. –

+0

Sprawdzałem nową rolę w szablonie gałązki za pomocą 'if is_granted ('ROLE_XYZ')'. Zmieniłem to na 'if app.user.hasRole ('ROLE_XYZ')' i teraz działa. Dziwne ... –

Odpowiedz

19

Spróbuj tego:

$em = $this->getDoctrine()->getManager(); 
$loggedInUser = $this->get('security.context')->getToken()->getUser(); 
$loggedInUser->addRole('ROLE_XYZ'); 

$em->persist($loggedInUser); 
$em->flush(); 

$token = new \Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken(
    $loggedInUser, 
    null, 
    'main', 
    $loggedInUser->getRoles() 
); 

$this->container->get('security.context')->setToken($token); 
+0

Dzięki! Jak pokazałeś, sztuczka polegała na zastąpieniu tokena bezpieczeństwa nowym, nowym rolami. –

+1

Mogę potwierdzić, że to rozwiązanie nadal działa w wersji 2.6.3 –

+1

Nadal działa w 2.8 – Brett

10

Nie ma potrzeby tokena resetowania w poprzedniej odpowiedzi. Tylko w swojej bezpieczeństwa pliku konfiguracyjnego (security.yml, etc ...), dodaj to:

security: 
    always_authenticate_before_granting: true 
+1

Jeśli jest to kwestia odnosząca się do innej odpowiedzi, myślę, że lepiej byłoby być komentarzem do tej odpowiedzi, niż samą odpowiedzią. – beresfordt

+2

Wygląda na to, że potrzebujesz takiej reputacji. Inteligentne ruchy wszystko wokół. – Marc

+0

Nie wiesz, jak jestem wdzięczna – Cavid

8

Chociaż odpowiedź zostanie zaakceptowana, Symfony faktycznie ma natywny sposób na odświeżenie obiektu użytkownika. Kredyt trafia do Joeriego Timmermansa za this article.

Kroki odświeżania obiektu użytkownika:

  1. Dodać podmiot użytkownika implementować interfejs

Symfony \ Komponent \ Security \ Rdzeń \ \ User EquatableInterface

  1. Implementacja funkcji abstrakcji isEqualTo:

public function isEqualTo(UserInterface $user) 
 
{ 
 
    if ($user instanceof User) { 
 
     // Check that the roles are the same, in any order 
 
     $isEqual = count($this->getRoles()) == count($user->getRoles()); 
 
     if ($isEqual) { 
 
      foreach($this->getRoles() as $role) { 
 
       $isEqual = $isEqual && in_array($role, $user->getRoles()); 
 
      } 
 
     } 
 
     return $isEqual; 
 
    } 
 

 
    return false; 
 
}

Powyższy kod odświeża obiekt użytkownika, czy jakieś nowe role dodaną. Ta sama zasada odnosi się również do innych porównywanych pól.

+0

Dzięki za to !, do tej pory nie rozumiałem EquatableInterface! – wonzbak

+2

Po prostu FYI: Jeśli zaimplementujesz 'EquatableInterface', możesz również dodać inne porównania, które normalnie robi Symfony (dopóki nie zaimplementujesz EquatableInterface). Jeśli twój użytkownik implementuje AdvancedUserInterface, możesz chcieć dodać porównania dla 'isAccountNonExpired',' isAccountNonLocked', 'isCredentialsNonExpired' i' isEnabled'. Sprawdź https://github.com/symfony/security/blob/v3.1.2/Core/Authentication/Token/AbstractToken.php#L250-L282 – simshaun

2
$user = $this->getUser(); 
$userManager = $this->get('fos_user.user_manager'); 
$user->addRole('ROLE_TEACHER'); 
$userManager->updateUser($user); 
$newtoken = new \Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken($user,null,'main', $user->getRoles()); 
$token = $this->get('security.token_storage')->setToken($newtoken); 
Powiązane problemy