使用新的 Symfony 5 Authenticator 注册后如何手动验证用户?

Rod*_*gel 6 php symfony symfony5

Symfony的5已经改变了其防护装置的认证方法,以一个新的Passport基于一个,使用新的安全配置:enable_authenticator_manager: true;

我想知道如何在我的控制器中的注册表单方法中对用户进行身份验证,在 ORM(Doctrine)持久化用户之后;

我已成功使用登录表单对用户进行身份验证,但我仍然不知道如何手动执行此操作。

小智 13

对于 Symfony 6,根据 @Cerad 关于 UserAuthenticatorInterface::authenticateUser() 的评论找到工作解决方案。

我在 services.yaml 中声明了我的 RegisterController 并带有重要参数(这就是原因):

App\Controller\RegisterController:
    arguments:
        $authenticator: '@security.authenticator.form_login.main'
Run Code Online (Sandbox Code Playgroud)

所以我的 RegisterController 现在看起来像:

class RegisterController extends AbstractController
{
    public function __construct(
        private FormLoginAuthenticator $authenticator
    ) {
    }

    #[Route(path: '/register', name: 'register')]
    public function register(
        Request $request,
        UserAuthenticatorInterface $authenticatorManager,
    ): RedirectResponse|Response {
        // some create logic
        ...

        // auth, not sure if RememberMeBadge works, keep testing
        $authenticatorManager->authenticateUser($user, $this->authenticator, $request, [new RememberMeBadge()]);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 激活“记住我”需要启用徽章:$rememberMe = new RememberMeBadge(); $rememberMe->enable(); $authenticatorManager->authenticateUser($user, $this->authenticator, $request, [$rememberMe]); (5认同)

Rod*_*gel 6

根据Cerad的评论,这是完整的答案。

以下只是与问答相关的代码部分。这些不是完整的文件。

此外,这仅适用于使用保护来验证用户的Symfony ^5.2 。

/* config/packages/security.yaml */

security:
    enable_authenticator_manager: true
    firewalls:
        main:
            custom_authenticators:
                - App\Security\SecurityAuthenticator
Run Code Online (Sandbox Code Playgroud)
/* src/Security/SecurityAuthenticator.php */

use Symfony\Component\Security\Http\Authenticator\AbstractLoginFormAuthenticator;

/* automatically generated with the make:auth command,
     the important part is to undestand that this is not a Guard implement 
     for the Authenticator class */
class SecurityAuthenticator extends AbstractLoginFormAuthenticator
{
  
}
Run Code Online (Sandbox Code Playgroud)
/* src/Controller/RegistrationController.php */

use App\Entity\User;
use App\Form\RegistrationFormType;
use App\Security\SecurityAuthenticator;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Security\Http\Authentication\UserAuthenticatorInterface;

class RegistrationController extends AbstractController
{

    /**
     * @Route("/register", name="app_register")
     */
    public function register(
        Request $request, 
        UserPasswordEncoderInterface $passwordEncoder, 
        UserAuthenticatorInterface $authenticator, 
        SecurityAuthenticator $formAuthenticator): Response
    {
      /* Automatically generated by make:registration-form, but some changes are
         needed, like the auto-wiring of the UserAuthenticatorInterface and 
         SecurityAuthenticator */
        $user = new User();
        $form = $this->createForm(RegistrationFormType::class, $user);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            // encode the plain password
            $user->setPassword($passwordEncoder->encodePassword($user, $form->get('password')->getData()));

            $entityManager = $this->getDoctrine()->getManager();
            $entityManager->persist($user);
            $entityManager->flush();

            // substitute the previous line (redirect response) with this one.
            return $authenticator->authenticateUser(
                $user, 
                $formAuthenticator, 
                $request); 
        }

        return $this->render('registration/register.html.twig', [
            'registrationForm' => $form->createView(),
        ]);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 好答案。我想知道如何获取当前防火墙的用户身份验证器。我从来没有想过只是打字暗示反对它。用户验证器实际上是一个安全捆绑类,它根据主请求确定当前的防火墙。好东西要知道。 (2认同)