为什么 isPasswordValid() 函数总是 return false?
Why isPasswordValid() function always return false?
我正在使用 Symfony4 开发一个简单的重置密码系统。
不知道为什么isPasswordValid()
总是returnfalse?
我正在使用 Bcrypt 来散列密码
这是 Security.yaml 的一些代码:
security:
encoders:
App\Entity\User:
algorithm: bcrypt
我不知道为什么 isPasswordValid()
总是 return 错误。
我手动试过这个:
$pass="000000000";
dump($encoder->isPasswordValid($user, $pass));
die();
它转储错误..
这是我在控制器上写的函数:
/**
* @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(),
]);
}
这是 ResetPassType 的形式:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('oldPassword', PasswordType::class, [
'mapped' => false,])
->add('password',PasswordType::class)
;
}
简答:您正在使用新密码作为旧密码的哈希值。
解释:
我猜你将你的表单绑定到你的用户 class。
您表单中的 password
字段是 mapped,这意味着它会更新您用户的 password
属性.
因此,由于属性应该包含“旧密码”的散列,但包含您的新密码,因此无法验证。
解决和改进:
最快的解决方案是 "取消映射" password
字段或删除 data_class
表单选项,并替换控制器中的一行:
// before: $newPassword = $user->getPassword();
$newPassword = $form->get('password')->getData();
我建议:
- 解除表单与您的用户的绑定class
- 为您的
oldPassword
字段使用 UserPassword 验证约束
- 使用
$form->getData()
获取表单数据,而不是手动访问 $request
你会更改你的表单,因为如果你保留字段密码,用户的密码也会被表单更改,所以正确的方法是:
-在您的表单中:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('oldPassword', PasswordType::class, [
'mapped' => false,])
->add('newPassword',PasswordType::class, [
'mapped' => false,])
;
}
然后在您的控制器中更改获取新密码的方式
$oldPassword = $request->request->get('reset_pass')['oldPassword'];
$newPassword = $request->request->get('reset_pass')['newPassword'];
玩得开心:)
我正在使用 Symfony4 开发一个简单的重置密码系统。
不知道为什么isPasswordValid()
总是returnfalse?
我正在使用 Bcrypt 来散列密码 这是 Security.yaml 的一些代码:
security:
encoders:
App\Entity\User:
algorithm: bcrypt
我不知道为什么 isPasswordValid()
总是 return 错误。
我手动试过这个:
$pass="000000000";
dump($encoder->isPasswordValid($user, $pass));
die();
它转储错误..
这是我在控制器上写的函数:
/**
* @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(),
]);
}
这是 ResetPassType 的形式:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('oldPassword', PasswordType::class, [
'mapped' => false,])
->add('password',PasswordType::class)
;
}
简答:您正在使用新密码作为旧密码的哈希值。
解释:
我猜你将你的表单绑定到你的用户 class。
您表单中的 password
字段是 mapped,这意味着它会更新您用户的 password
属性.
因此,由于属性应该包含“旧密码”的散列,但包含您的新密码,因此无法验证。
解决和改进:
最快的解决方案是 "取消映射" password
字段或删除 data_class
表单选项,并替换控制器中的一行:
// before: $newPassword = $user->getPassword();
$newPassword = $form->get('password')->getData();
我建议:
- 解除表单与您的用户的绑定class
- 为您的
oldPassword
字段使用 UserPassword 验证约束 - 使用
$form->getData()
获取表单数据,而不是手动访问$request
你会更改你的表单,因为如果你保留字段密码,用户的密码也会被表单更改,所以正确的方法是:
-在您的表单中:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('oldPassword', PasswordType::class, [
'mapped' => false,])
->add('newPassword',PasswordType::class, [
'mapped' => false,])
;
}
然后在您的控制器中更改获取新密码的方式
$oldPassword = $request->request->get('reset_pass')['oldPassword'];
$newPassword = $request->request->get('reset_pass')['newPassword'];
玩得开心:)