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

时间:2013-10-31 18:14:31

标签: php symfony fosuserbundle

比如说我向控制器中当前经过身份验证的用户授予新角色,如下所示:

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

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

在下一页加载时,我再次抓住经过身份验证的用户:

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

他们没有被授予角色。我猜这是因为用户存储在会话中并需要刷新。

我该怎么做?

如果有所作为,我正在使用FOSUserBundle。

5 个答案:

答案 0 :(得分:22)

试试这个:

$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);

答案 1 :(得分:13)

在上一个答案中不需要重置令牌。只是,在你的安全配置文件(security.yml等等)中,添加:

security:
    always_authenticate_before_granting: true

答案 2 :(得分:12)

虽然接受了答案,但Symfony实际上有一种刷新User对象的本机方式。感谢this article的Joeri Timmermans。

刷新用户对象的步骤:

  1. 让您的用户实体实现界面
  2.   

    的Symfony \元器件\安全\核心\用户\ EquatableInterface

    1. 实现抽象函数isEqualTo:
    2. 
      
      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;
      }
      
      
      

      如果添加了任何新角色,则上面的代码会刷新User对象。对于您比较的其他领域,同样的原则也适用。

答案 3 :(得分:3)

$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);

答案 4 :(得分:0)

在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 {
            //...
        }
    }
相关问题