为什么 isPasswordValid() 函数总是返回 false?

Meh*_* Di 1 php change-password symfony symfony4

我正在使用 Symfony4 开发一个简单的重置密码系统。

我不知道为什么isPasswordValid()总是返回false

我正在使用Bcrypt来哈希密码这是 Security.yaml 的一些代码:

security:
    encoders:
        App\Entity\User:
            algorithm: bcrypt
Run Code Online (Sandbox Code Playgroud)

我不知道为什么isPasswordValid()总是返回 false。我手动尝试过这个:

$pass="000000000";
dump($encoder->isPasswordValid($user, $pass));
die();
Run Code Online (Sandbox Code Playgroud)

它转储错误..

这是我在控制器上编写的函数:

/**
 * @Route("/password", name="change_pass", methods={"GET","POST"})
 * @IsGranted("ROLE_USER")
 */
public function edit(Request $request,UserPasswordEncoderInterface $encoder): Response
{

    $user = $this->getUser();

    $form = $this->createForm(ResetPassType::class, $user);
    $form->handleRequest($request);

    if ($form->isSubmitted() && $form->isValid()) {

        $oldPassword = $request->request->get('reset_pass')['oldPassword'];
        $newPassword = $user->getPassword();

        if ($encoder->isPasswordValid($user, $oldPassword)) {
            $hash = $encoder->encodePassword($user,$newPassword);
            $user->setPassword($hash);
            $this->getDoctrine()->getManager()->flush();
            $this->addFlash('success', 'Your password is succesfully changed');
        }else {
            $this->addFlash('fail', 'old password is wrong');
        }

    }
    $this->getDoctrine()->getManager()->refresh($user);

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

这是 ResetPassType 的形式:

   public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
        ->add('oldPassword', PasswordType::class, [
            'mapped' => false,])
        ->add('password',PasswordType::class)
        ;
    }
Run Code Online (Sandbox Code Playgroud)

Aym*_*Dev 6

简短的回答:您正在使用新密码作为旧密码的哈希值。


说明:
我猜您将表单绑定到了您的用户类。password您表单中的字段已被映射,这意味着它会更新您的用户的password属性。

因此,由于该属性应包含“旧密码”的哈希值,但包含您的新密码,因此无法验证。


解决方案和改进:
最快的解决方案是“取消映射”字段password或删除data_class表单选项,并替换控制器中的一行:

// before: $newPassword = $user->getPassword();
$newPassword = $form->get('password')->getData();
Run Code Online (Sandbox Code Playgroud)

我建议:

  • 取消表单与您的用户类的绑定
  • 对您的字段使用UserPassword验证约束oldPassword
  • 使用而不是手动$form->getData()访问来获取表单数据$request