douying8666
2013-10-31 18:14
浏览 20
已采纳

Symfony 2.3:如何从数据库中刷新经过身份验证的用户?

Say for example I grant a new role to the currently authenticated user in a controller, like so:

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

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

On the next page load, when I grab the authenticated user again:

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

They are not granted the role. I am guessing this is because the user is stored in the session and needs to be refreshed.

How do I do this?

I am using FOSUserBundle if that makes a difference.

  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

5条回答 默认 最新

  • dongyanju0945 2013-10-31 22:19
    已采纳

    Try this:

    $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);
    
    打赏 评论
  • drlndkhib08556095 2015-02-28 12:47

    There's no need for the token reset in the previous answer. Just, in your security config file (security.yml, etc...), add this:

    security:
        always_authenticate_before_granting: true
    
    打赏 评论
  • duanhui1185 2015-08-23 21:46

    While an answer is accepted, Symfony actually has a native way to refresh the User object. Credit goes out to Joeri Timmermans for this article.

    Steps for refreshing the User object:

    1. Make your User entity implement the interface

    Symfony\Component\Security\Core\User\EquatableInterface

    1. Implement the abstract function 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;
    }

    The code above refreshes the User object if any new roles are added. The same principle also holds true for other fields you compare.

    </div>
    
    打赏 评论
  • dox19458 2017-10-16 18:13
    $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);
    
    打赏 评论
  • duanmorong9597 2019-08-27 14:26

    In Symfony 4

    public function somename(ObjectManager $om, TokenStorageInterface $ts)
        {
            $user = $this->getUser();
            if ($user) {
                $user->setRoles(['ROLE_VIP']); //change/update role
                // persist if need
                $om->flush();
                $ts->setToken(
                    new PostAuthenticationGuardToken($user, 'main', $user->getRoles())
                );
                //...
            } else {
                //...
            }
        }
    
    打赏 评论

相关推荐 更多相似问题