skip to Main Content

I’m working on an application using Symfony 4.3. I’m currently working on a function to modify a user’s password and in order to do so I’m first verifying that the user knows his password before changing it. I’m doing this by typing the value of his current password in a form type. However, the php password_verify function doesn’t seem to recognize the user’s actual password when he wants to change it. I’m using the symfony form builder which allows me to get values without explicitly setting them myself. We are able to recuperate the user’s password correctly and the hash but the function always returns false. I’m using the ‘auto’ algorithm to encrypt the passwords in security.yaml.

I have tried everything, from using single quotes to double quotes, from using plain text for both the word password and the encoded version of it like so:password_verify('password','encoded_version') or using the function dynamically. Below is some code which I have written. As previously stated I’m using the symfony form builder.

FORM TO ENTER THE PASSWORD

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,
        ]);
    }
}

CODE TO VERIFY THAT THE PASSWORDS MATCH

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();


            }

I’m constantly falling in the condition where the passwords do not match although my dumps are working which means the information is being recuperated. Thanks!

2

Answers


  1. Use the UserPasswordEncoder Class see 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)) {
    
         }
    
    Login or Signup to reply.
  2. Symfony has a constraint to verify current password in a submitted form: UserPassword

    You can follow the documentation and add a dedicated $oldPassword to your user entity with this constraint, or you can add it directly to the form type, like so:

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

    Note that Symfony also has a constraint to check that two inputs are identical (e.g. “confirm password” field): RepeatedType. Consider using these two constraints instead of manually validating user input in your controller.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search