Symfony 4 - 连接时删除您自己的用户帐户的良好做法
Symfony 4 - Good practice to remove your own user account while connected
我希望我的用户能够删除他们自己的用户帐户。我做了一个 SecurityController
,其中有我的 3 个函数 login
、logout
和 deleteUser
。当我删除数据库中的当前用户时,出现此错误:
You cannot refresh a user from the EntityUserProvider that does not contain an identifier. The user object has to be serialized with its own identifier mapped by Doctrine.
当我删除另一个用户时,它可以正常工作,因为他没有连接。
我是否必须序列化用户并通过服务传递它,注销用户然后在服务中将其删除?或者我可以清除控制器中的 PHP 会话但我不知道如何使用 symfony4 我认为它自版本 4 以来发生了变化。
<?php
namespace App\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationChecker;
use App\Entity\User;
use App\Form\UserType;
class SecurityController extends Controller
{
/**
* @Route("/createAdmin", name="create_admin")
*/
public function createAdminUser(Request $request, UserPasswordEncoderInterface $passwordEncoder)
{
$usersRepo = $this->getDoctrine()->getRepository(User::class);
$uCount = $usersRepo->countAllUsers();
if ($uCount == 0)
{
$user = new User();
$form = $this->createForm(UserType::class, $user, array(
'is_fresh_install' => true,
));
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
// Encode the password
$password = $passwordEncoder->encodePassword($user, $user->getPlainPassword());
$user->setPassword($password);
// save the User
$em = $this->getDoctrine()->getManager();
$em->persist($user);
$em->flush();
// Do what you want here before redirecting the user
return $this->redirectToRoute('login');
}
return $this->render('security/register_admin_user.html.twig', array(
'form' => $form->createView(),
));
} else {
if ($this->getUser())
{
return $this->redirectToRoute('user_account');
} else {
return $this->redirectToRoute('login');
}
}
}
/**
* @Route("/login", name="login")
*/
public function login(Request $request, AuthenticationUtils $authUtils)
{
$usersRepo = $this->getDoctrine()->getRepository(User::class);
$uCount = $usersRepo->countAllUsers();
if ($uCount == 0)
{
return $this->redirectToRoute('create_admin');
} else {
$error = $authUtils->getLastAuthenticationError();
$lastUsername = $authUtils->getLastUsername();
return $this->render('security/login.html.twig', array(
'last_username' => $lastUsername,
'error' => $error,
));
}
}
/**
* @Route("/logout", name="logout")
*/
public function logout()
{
}
/**
* @Route("/delete_user/{id}", name="delete_user")
*/
public function deleteUser($id)
{
$em = $this->getDoctrine()->getManager();
$usrRepo = $em->getRepository(User::class);
$user = $usrRepo->find($id);
$em->remove($user);
$em->flush();
return $this->redirectToRoute('user_registration');
}
}
我认为你必须序列化用户并通过service.Just检查以前的版本,你会发现问题的。
解决方案:
在使用此方法删除数据库中的用户条目之前,您必须清除会话:
<?php
use Symfony\Component\HttpFoundation\Session\Session;
// In your deleteUser function...
$currentUserId = $this->getUser()->getId();
if ($currentUserId == $id)
{
$session = $this->get('session');
$session = new Session();
$session->invalidate();
}
我不知道为什么$this->get('session')->invalidate();
不能直接工作...如果有人知道:)
我发现这也是一个很好的解决方案,这是一个公认的答案,但您也可以简单地将用户重定向到注销路径。
这对我来说在 Symfony 4.4
中没有任何问题
我希望我的用户能够删除他们自己的用户帐户。我做了一个 SecurityController
,其中有我的 3 个函数 login
、logout
和 deleteUser
。当我删除数据库中的当前用户时,出现此错误:
You cannot refresh a user from the EntityUserProvider that does not contain an identifier. The user object has to be serialized with its own identifier mapped by Doctrine.
当我删除另一个用户时,它可以正常工作,因为他没有连接。 我是否必须序列化用户并通过服务传递它,注销用户然后在服务中将其删除?或者我可以清除控制器中的 PHP 会话但我不知道如何使用 symfony4 我认为它自版本 4 以来发生了变化。
<?php
namespace App\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationChecker;
use App\Entity\User;
use App\Form\UserType;
class SecurityController extends Controller
{
/**
* @Route("/createAdmin", name="create_admin")
*/
public function createAdminUser(Request $request, UserPasswordEncoderInterface $passwordEncoder)
{
$usersRepo = $this->getDoctrine()->getRepository(User::class);
$uCount = $usersRepo->countAllUsers();
if ($uCount == 0)
{
$user = new User();
$form = $this->createForm(UserType::class, $user, array(
'is_fresh_install' => true,
));
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
// Encode the password
$password = $passwordEncoder->encodePassword($user, $user->getPlainPassword());
$user->setPassword($password);
// save the User
$em = $this->getDoctrine()->getManager();
$em->persist($user);
$em->flush();
// Do what you want here before redirecting the user
return $this->redirectToRoute('login');
}
return $this->render('security/register_admin_user.html.twig', array(
'form' => $form->createView(),
));
} else {
if ($this->getUser())
{
return $this->redirectToRoute('user_account');
} else {
return $this->redirectToRoute('login');
}
}
}
/**
* @Route("/login", name="login")
*/
public function login(Request $request, AuthenticationUtils $authUtils)
{
$usersRepo = $this->getDoctrine()->getRepository(User::class);
$uCount = $usersRepo->countAllUsers();
if ($uCount == 0)
{
return $this->redirectToRoute('create_admin');
} else {
$error = $authUtils->getLastAuthenticationError();
$lastUsername = $authUtils->getLastUsername();
return $this->render('security/login.html.twig', array(
'last_username' => $lastUsername,
'error' => $error,
));
}
}
/**
* @Route("/logout", name="logout")
*/
public function logout()
{
}
/**
* @Route("/delete_user/{id}", name="delete_user")
*/
public function deleteUser($id)
{
$em = $this->getDoctrine()->getManager();
$usrRepo = $em->getRepository(User::class);
$user = $usrRepo->find($id);
$em->remove($user);
$em->flush();
return $this->redirectToRoute('user_registration');
}
}
我认为你必须序列化用户并通过service.Just检查以前的版本,你会发现问题的。
解决方案:
在使用此方法删除数据库中的用户条目之前,您必须清除会话:
<?php
use Symfony\Component\HttpFoundation\Session\Session;
// In your deleteUser function...
$currentUserId = $this->getUser()->getId();
if ($currentUserId == $id)
{
$session = $this->get('session');
$session = new Session();
$session->invalidate();
}
我不知道为什么$this->get('session')->invalidate();
不能直接工作...如果有人知道:)
我发现这也是一个很好的解决方案,这是一个公认的答案,但您也可以简单地将用户重定向到注销路径。 这对我来说在 Symfony 4.4
中没有任何问题