Implement change password in Symfony2

后端 未结 5 1225
孤城傲影
孤城傲影 2020-12-07 17:45

What is the best way to implement change password functionality in Symfony2? Right now I\'m using this:

$builder->add(\'password\', \'repeated\', array(
         


        
相关标签:
5条回答
  • 2020-12-07 18:33

    I use a action from my controller:

    public function changepasswordAction(Request $request) {
        $session = $request->getSession();
    
        if($request->getMethod() == 'POST') {
            $old_pwd = $request->get('old_password');
            $new_pwd = $request->get('new_password');
            $user = $this->getUser();
            $encoder = $this->container->get('security.encoder_factory')->getEncoder($user);
            $old_pwd_encoded = $encoder->encodePassword($old_pwd, $user->getSalt());
    
            if($user->getPassword() != $old_pwd_encoded) {
                $session->getFlashBag()->set('error_msg', "Wrong old password!");
            } else {
                $new_pwd_encoded = $encoder->encodePassword($new_pwd, $user->getSalt());
                $user->setPassword($new_pwd_encoded);
                $manager = $this->getDoctrine()->getManager();
                $manager->persist($user);
    
                $manager->flush();
                $session->getFlashBag()->set('success_msg', "Password change successfully!");
            }
            return $this->render('@adminlte/profile/change_password.html.twig');
        }
    
        return $this->render('@adminlte/profile/change_password.html.twig', array(
    
        ));
    }
    
    0 讨论(0)
  • 2020-12-07 18:38

    You have to either create another model with two fields:

    • one for the current password;
    • and the other for the new one.

    Or add a non-persisted property to your user model like the FOSUserBundle does (see the plainPassword property).

    So once you checked both current and new password are valid, you encode the new password and replace the old one with it.

    0 讨论(0)
  • 2020-12-07 18:41

    Can't You get old password from User before binding form?

    // in action:
    $oldpassword = $user->getPassword();
    
    if ($request->getMethod() == 'POST') 
            {
                $form->bindRequest($request);
    
                if ($form->isValid()) 
                {
                    // check password here (by hashing new one)
    
    0 讨论(0)
  • 2020-12-07 18:43

    Since Symfony 2.3 you can easily use UserPassword validation constraint.

    Acme\UserBundle\Form\Model\ChangePassword.php

    namespace Acme\UserBundle\Form\Model;
    
    use Symfony\Component\Security\Core\Validator\Constraints as SecurityAssert;
    use Symfony\Component\Validator\Constraints as Assert;
    
    class ChangePassword
    {
        /**
         * @SecurityAssert\UserPassword(
         *     message = "Wrong value for your current password"
         * )
         */
         protected $oldPassword;
    
        /**
         * @Assert\Length(
         *     min = 6,
         *     minMessage = "Password should by at least 6 chars long"
         * )
         */
         protected $newPassword;
    }
    

    Acme\UserBundle\Form\ChangePasswordType.php

    namespace Acme\UserBundle\Form;
    
    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\FormBuilderInterface;
    use Symfony\Component\OptionsResolver\OptionsResolverInterface;
    
    class ChangePasswordType extends AbstractType
    {
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder->add('oldPassword', 'password');
            $builder->add('newPassword', 'repeated', array(
                'type' => 'password',
                'invalid_message' => 'The password fields must match.',
                'required' => true,
                'first_options'  => array('label' => 'Password'),
                'second_options' => array('label' => 'Repeat Password'),
            ));
        }
    
        public function setDefaultOptions(OptionsResolverInterface $resolver)
        {
            $resolver->setDefaults(array(
                'data_class' => 'Acme\UserBundle\Form\Model\ChangePassword',
            ));
        }
    
        public function getName()
        {
            return 'change_passwd';
        }
    }
    

    Acme\UserBundle\Controller\DemoController.php

    namespace Acme\UserBundle\Controller;
    
    use Symfony\Bundle\FrameworkBundle\Controller\Controller;
    use Symfony\Component\HttpFoundation\Request;
    use Acme\UserBundle\Form\ChangePasswordType;
    use Acme\UserBundle\Form\Model\ChangePassword;
    
    class DemoController extends Controller
    {
        public function changePasswdAction(Request $request)
        {
          $changePasswordModel = new ChangePassword();
          $form = $this->createForm(new ChangePasswordType(), $changePasswordModel);
    
          $form->handleRequest($request);
    
          if ($form->isSubmitted() && $form->isValid()) {
              // perform some action,
              // such as encoding with MessageDigestPasswordEncoder and persist
              return $this->redirect($this->generateUrl('change_passwd_success'));
          }
    
          return $this->render('AcmeUserBundle:Demo:changePasswd.html.twig', array(
              'form' => $form->createView(),
          ));      
        }
    }
    
    0 讨论(0)
  • 2020-12-07 18:46

    Just add this to your form type:

    $builder->add('oldPlainPassword', \Symfony\Component\Form\Extension\Core\Type\PasswordType::class, array(
        'constraints' => array(
            new \Symfony\Component\Security\Core\Validator\Constraints\UserPassword(),
        ),
        'mapped' => false,
        'required' => true,
        'label' => 'Current Password',
    ));
    
    0 讨论(0)
提交回复
热议问题