Symfony4:密码更改问题

Symfony4: Password Changing Issues

我被困在如何通过在 symfony 中提交表单来更改密码 - 我不知道如何解决它,因为它的行为似乎有所不同。

所以首先 - 我正在构建一个自定义表单,用户在其中输入他们的旧密码,然后输入两次新密码。这是我的表单类型:

UserPasswordType.php

<?php

namespace App\Form;

use App\Entity\User;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Security\Core\Validator\Constraints\UserPassword;

class UserPasswordType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            //basically just a unmapped password field
            ->add('password_current', PasswordType::class, [
                'label' => 'user.password.current', 
                'mapped' => false,
                /*'constraints' => new UserPassword()*/
            ])
            //RepeatedType to get a confirm password field
            ->add('password', RepeatedType::class, [
                'type' => PasswordType::class,
                'first_name' => 'new', 
                'first_options' => ['label' => 'user.password.new'], 
                'second_name' => 'confirm', 
                'second_options' => ['label' => 'user.password.confirm']
            ])
            ->add('save', SubmitType::class, ['label' => 'app.save']);
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => User::class
        ]);
    }
}

这是我的控制器:

    /**
     * @Route("/user/settings", name="app_user_settings", defaults={"_locale":"%locale%"})
     * @IsGranted("ROLE_USER")
     */
    public function user_settings(Request $request, UserPasswordEncoderInterface $passwordEncoder)
    {
        $user = $this->getUser();
        $form = $this->createForm(UserPasswordType::class, $user);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $em = $this->getDoctrine()->getManager();

            //earlier: $current = $request->get('password_current'); - but does not work anymore?
            $current = $form['password']->getData();
            if ($passwordEncoder->isPasswordValid($user, $current)) { //fails always?
                $confirm = $form['password_confirm']->getData();
                $user->setPassword($passwordEncoder->encodePassword($user, $confirm));

                $em->persist($user);
                $em->flush();

                $this->addFlash('success', 'status.success.text');
                return $this->redirectToRoute('app_user');
            }
            $this->addFlash('danger', 'status.danger.text');
        }

        return $this->render('user/settings/index.html.twig', ['form' => $form->createView()]);
    }

所以这是我的问题:

可悲的是,我现在真的很困惑,因为我的大部分东西昨天都工作了。任何人都知道如何处理这些问题?谢谢

好吧,我终于找到了解决办法。我将表单类型映射到实体。因此,每当我输入新密码时,我的 "old" 密码实际上就是新密码。这使得每次验证都失败。

所以只需像这样创建一个未映射的表单类型:

表格类型

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('password_current', PasswordType::class, ['label' => 'user.password.current', 'constraints' => new UserPassword()])
            ->add('password', RepeatedType::class, ['type' => PasswordType::class, 'first_name' => 'new', 'first_options' => ['label' => 'user.password.new'], 'second_name' => 'confirm', 'second_options' => ['label' => 'user.password.confirm']])
            ->add('save', SubmitType::class, ['label' => 'app.save']);
    }

    /* Remove entire function
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => User::class
        ]);
    }*/

控制器

    //remove $user in createForm function
    //$form = $this->createForm(UserPasswordType::class, $user);
    $form = $this->createForm(UserPasswordType::class);

有趣的副作用。这也消除了我遇到的所有其他问题。