2013-10-31 24 views
13

Nói ví dụ Tôi cho một vai trò mới cho người dùng hiện thực trong một bộ điều khiển, như vậy:Symfony 2.3: Làm cách nào để làm mới người dùng đã xác thực từ cơ sở dữ liệu?

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

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

Trên tải trang tiếp theo, khi tôi lấy người dùng xác thực một lần nữa:

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

Họ không được cấp vai trò. Tôi đoán điều này là do người dùng được lưu trữ trong phiên và cần phải được làm mới.

Làm cách nào để thực hiện việc này?

Tôi đang sử dụng FOSUserBundle nếu điều đó tạo sự khác biệt.

+0

Cơ sở dữ liệu có được cập nhật không? – cheesemacfly

+0

Có cơ sở dữ liệu được cập nhật. Vì vậy, nếu tôi đăng xuất và trong một lần nữa thì vai trò mới được phản ánh. –

+0

Tôi đã kiểm tra vai trò mới trong một mẫu khuôn mẫu bằng cách sử dụng 'if is_granted ('ROLE_XYZ')'. Tôi đã thay đổi điều này thành 'if app.user.hasRole ('ROLE_XYZ')' và bây giờ nó đang hoạt động. Lạ ... –

Trả lời

19

Hãy thử điều này:

$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

Cảm ơn! Như bạn đã chỉ ra, mẹo là thay thế mã thông báo bảo mật bằng một mã thông báo mới có vai trò mới. –

+1

Tôi có thể xác nhận rằng giải pháp này vẫn hoạt động trên 2.6.3 –

+1

Vẫn hoạt động trong 2.8 – Brett

10

Không cần cho các thiết lập lại thẻ trong câu trả lời trước. Chỉ cần, an ninh tập tin cấu hình của bạn (security.yml, vv ...), thêm này:

security: 
    always_authenticate_before_granting: true 
+1

Nếu đây là một điểm liên quan đến câu trả lời khác, tôi nghĩ rằng nó sẽ phù hợp hơn để nhận xét về câu trả lời đó, chứ không phải là câu trả lời theo đúng nghĩa của nó – beresfordt

+2

Dường như bạn cần một số danh tiếng để làm điều đó. Di chuyển thông minh tất cả arround. – Marc

+0

bạn không biết làm thế nào tôi đánh giá cao – Cavid

8

Trong khi một câu trả lời được chấp nhận, Symfony thực sự có một cách tự nhiên để làm mới các đối tượng người dùng. Tín dụng chuyển đến Joeri Timmermans cho this article.

Các bước để làm mới các đối tượng sử dụng:

  1. Hãy thực thể tài khoản của bạn thực hiện các giao diện

Symfony \ Component \ Security \ Lõi \ User \ EquatableInterface

  1. Triển khai hàm trừu tượng 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; 
 
}

Đoạn mã trên làm mới đối tượng người dùng nếu bất kỳ vai trò mới được thêm vào. Nguyên tắc tương tự cũng đúng với các trường khác mà bạn so sánh.

+0

Cảm ơn điều này !, cho đến bây giờ tôi không hiểu EquatableInterface! – wonzbak

+2

Chỉ cần một FYI: Nếu bạn thực hiện 'EquatableInterface', bạn cũng có thể muốn thêm các so sánh khác mà Symfony sẽ tạo ra (cho đến khi bạn thực hiện EquatableInterface). Nếu người dùng của bạn cũng thực hiện AdvancedUserInterface, thì bạn có thể muốn thêm so sánh cho 'isAccountNonExpired',' isAccountNonLocked', 'isCredentialsNonExpired' và' isEnabled'. Xem 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); 
Các vấn đề liên quan