【问题标题】:symfony 4 php password_verify not working correctlysymfony 4 php password_verify 无法正常工作
【发布时间】:2020-02-18 17:40:24
【问题描述】:

我正在使用 Symfony 4.3 开发一个应用程序。我目前正在研究修改用户密码的功能,为此我首先验证用户在更改密码之前是否知道他的密码。我通过在表单类型中输入他当前密码的值来做到这一点。但是,当用户想要更改密码时,php password_verify 函数似乎无法识别用户的实际密码。我正在使用 symfony 表单构建器,它允许我获取值而无需自己明确设置它们。我们能够正确恢复用户的密码和哈希,但该函数总是返回 false。我正在使用“自动”算法来加密security.yaml 中的密码。

我已经尝试了所有方法,从使用单引号到双引号,从使用纯文本作为密码和它的编码版本(如so:password_verify('password','encoded_version'))或动态使用函数。下面是我写的一些代码。如前所述,我正在使用 symfony 表单构建器。

输入密码的表格

class PasswordUpdateType extends AbstractType
{

    /**
     * Permet d'avoir la configuration d'un chanmp
     *
     * @param string $label
     * @param string $placeholder
     * @return array $options
     * @return array
     */
    private function getConfiguration($label, $placeholder, $options = []) {
        return array_merge([
            'label' => $label,
            'attr'=>[
                'placeholder'=>$placeholder
            ]
        ], $options);
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
        ->add('oldPassword', PasswordType::class, $this->getConfiguration("Ancien mot de passe","Saisier le mot de passe actuel"))
        ->add('newPassword', PasswordType::class, $this->getConfiguration("Nouveau mot de passe","Saisier le mot de passe actuel"))
        ->add('confirmPassword', PasswordType::class, $this->getConfiguration("Confirmer le mouveau mot de passe","Saisier le mot de passe actuel"))
        ;
    }

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

验证密码是否匹配的代码

public function updatePassword(Request $request, UserPasswordEncoderInterface $encoder, ObjectManager $manager) {
        $passwordUpdate = new PasswordUpdate();
        $user=$this->getUser();

        $form = $this->createForm(PasswordUpdateType::class, $passwordUpdate);

        $form->handleRequest($request);

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

            if(!password_verify($passwordUpdate->getOldPassword(),$user->getPassword())) {
                $form->get('oldPassword')->addError(new FormError("Le mot de passe saisi n'est pas le mot de passe actuel")); 
                //dump($passwordUpdate->getOldPassword());
                //dump(password_verify($passwordUpdate->getOldPassword(),$user->getPassword()));
                dump($passwordUpdate->getOldPassword());
                dump($encoder->encodePassword($user,$passwordUpdate->getOldPassword()));
                dump(gettype($user->getPassword()));
                dump(password_get_info($passwordUpdate->getOldPassword()));
                die();


            }

尽管我的转储工作正常,但我一直处于密码不匹配的状态,这意味着正在恢复信息。谢谢!

【问题讨论】:

  • 您应该使用 PasswordEncoder::isPasswordValid($encoded,$raw,$salt=null) 检查您的密码。如果您仍然遇到问题,请向我们展示 $encoded 和 $raw 的值。

标签: php symfony security change-password password-hash


【解决方案1】:

使用UserPasswordEncoder 类参见https://symfony.com/doc/current/security.html#c-encoding-passwords

 public function __construct(UserPasswordEncoderInterface $passwordEncoder)
 {
     $this->passwordEncoder = $passwordEncoder;
 }

public function updatePassword(..)
{
     // ....
     if(!$this->passwordEncoder->isPasswordValid($user, $password)) {

     }

【讨论】:

    【解决方案2】:

    Symfony 有一个约束来验证提交表单中的当前密码:UserPassword

    您可以按照文档并使用此约束将专用的$oldPassword 添加到您的用户实体,或者您可以将其直接添加到表单类型,如下所示:

    ->add('oldPassword', PasswordType::class, [
        'label' => 'Your current password',
        'mapped' => false,
        'constraints' => [
            new NotBlank(),
            new UserPassword()
        ]
    ])
    

    请注意,Symfony 也有一个约束来检查两个输入是否相同(例如“确认密码”字段):RepeatedType。考虑使用这两个约束,而不是在控制器中手动验证用户输入。

    【讨论】:

      猜你喜欢
      • 2023-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-15
      相关资源
      最近更新 更多