Symfony 2.3: Как обновить аутентифицированного пользователя из базы данных?


Скажем, например, я предоставляю новую роль текущему аутентифицированному пользователю в контроллере, например:

$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, если это имеет значение.

Author: Nada_Surf, 2013-10-31

4 answers

Попробуйте это:

$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);
 20
Author: dmnptr, 2013-10-31 22:19:58

В предыдущем ответе нет необходимости сбрасывать токен. Просто добавьте это в свой конфигурационный файл безопасности (security.yml и т. Д.):

security:
    always_authenticate_before_granting: true
 13
Author: Marc, 2015-02-28 12:47:39

Хотя ответ принят, у Symfony на самом деле есть собственный способ обновления пользовательского объекта. Спасибо Йори Тиммермансу за эту статью.

Шаги по обновлению объекта пользователя:

  1. Заставьте вашу пользовательскую сущность реализовать интерфейс

Symfony\Компонент\Безопасность\Ядро\Пользователь\Эквивалентный интерфейс

  1. Реализовать абстрактную функцию Равнозначно:

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;
}

Приведенный выше код обновляет объект пользователя, если добавляются какие-либо новые роли. Тот же принцип применим и к другим полям, которые вы сравниваете.

 11
Author: Thomas Maurstad Larsson, 2015-08-23 21:46:48
$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);
 2
Author: cretthie, 2017-10-16 18:13:46