Symfony 4 - 连接时删除您自己的用户帐户的好习惯

Posted

技术标签:

【中文标题】Symfony 4 - 连接时删除您自己的用户帐户的好习惯【英文标题】:Symfony 4 - Good practice to remove your own user account while connected 【发布时间】:2018-08-30 06:34:19 【问题描述】:

我希望我的用户能够删除他们自己的用户帐户。我创建了一个SecurityController,其中有我的三个函数loginlogoutdeleteUser。当我删除数据库中的当前用户时,会出现此错误:

您无法从不包含标识符的 EntityUserProvider 刷新用户。用户对象必须使用 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');

    


【问题讨论】:

您是否尝试在删除帐户之前先注销用户?如果这样做,听起来您破坏了当前会话 是的,但是我必须将用户重定向到登录页面,所以在控制器中我这样做:return $this->redirectToRoute('logout');所以用户会话会被 symfony 内部函数自动清除。退出后我什么都做不了。 考虑这个答案然后***.com/a/28828377/2538899 【参考方案1】:

解决方案:

您必须在使用此方法删除数据库中的用户条目之前清除会话:

<?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-&gt;get('session')-&gt;invalidate(); 不能直接工作......如果有人知道:)

【讨论】:

【参考方案2】:

我发现这也是一个很好的解决方案,这是一个公认的答案,但您也可以简单地将用户重定向到注销路线。 这对我来说在 Symfony 4.4 中没有任何问题

【讨论】:

【参考方案3】:

我认为您必须将用户序列化并通过服务传递。只需检查以前的版本,您就会发现问题。

【讨论】:

不,我不知道为什么我们必须在删除它之前对其进行序列化。 Symfony 在每次重新加载页面时都会从数据库中重新加载用户。会话也更新了。这就是为什么我们必须在将用户重定向到另一个页面之前清除会话。

以上是关于Symfony 4 - 连接时删除您自己的用户帐户的好习惯的主要内容,如果未能解决你的问题,请参考以下文章

Symfony 原则防止特定实体的记录删除

Firebase 删除用户问题

symfony 3.4.14 collectionType编辑和删除问题

npm学习之如何发布包更新发布包删除发布包

在验证用户与 Symfony 4 和 FOSUserBundle 连接后重定向用户

当用户在 Symfony 中更改语言环境时更新用户会话