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, если это имеет значение.
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);
В предыдущем ответе нет необходимости сбрасывать токен. Просто добавьте это в свой конфигурационный файл безопасности (security.yml и т. Д.):
security:
always_authenticate_before_granting: true
Хотя ответ принят, у Symfony на самом деле есть собственный способ обновления пользовательского объекта. Спасибо Йори Тиммермансу за эту статью.
Шаги по обновлению объекта пользователя:
- Заставьте вашу пользовательскую сущность реализовать интерфейс
Symfony\Компонент\Безопасность\Ядро\Пользователь\Эквивалентный интерфейс
- Реализовать абстрактную функцию Равнозначно:
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 = $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);