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

问题描述 投票:15回答:6

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

$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。

EDIT:该问题最初是在Symfony 2.3版的上下文中提出的,但下面也提供了最新版本的答案。

php symfony fosuserbundle
6个回答
23
投票

尝试一下:

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

13
投票

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

security:
    always_authenticate_before_granting: true

13
投票

虽然接受了一个答案,但Symfony实际上具有一种刷新User对象的本地方法。功劳[Joe Timmermans]的奖金为this article

刷新用户对象的步骤:

  1. 使您的用户实体实现界面

Symfony \ Component \ Security \ Core \ User \ EquatableInterface

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

如果添加了任何新角色,以上代码将刷新User对象。相同的原理也适用于您比较的其他字段。


4
投票
$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);

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 {
            //...
        }
    }

-1
投票

Symfony 5 +

$usr = $this->get('security.token_storage')->getToken()->getUser(); //get logged user
$usr->setPassword($params["password"]); //set new data
$token = new UsernamePasswordToken($usr, null,'main', $usr->getRoles()); 
this->container->get('security.token_storage')->setToken($token);
$this->container->get('session')->set('_security_main', serialize($token)); //update session info
© www.soinside.com 2019 - 2024. All rights reserved.