簡體   English   中英

Symfony:如何從數據庫中刷新經過身份驗證的用戶?

[英]Symfony: How do I refresh the authenticated user from the database?

例如,我在控制器中為當前經過身份驗證的用戶授予一個新角色,如下所示:

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

編輯:這個問題最初是在 Symfony 2.3 版的上下文中提出的,但下面也有更新版本的答案。

試試這個:

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

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

security:
    always_authenticate_before_granting: true

當一個答案被接受時,Symfony 實際上有一種本地方式來刷新 User 對象。 這篇文章要歸功於 Joeri Timmermans。

刷新用戶對象的步驟:

  1. 使您的 User 實體實現該接口

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 對象。 同樣的原則也適用於您比較的其他領域。

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

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM