在Symfony2中实现更改密码

kub*_*lav 24 forms security symfony doctrine-orm

在Symfony2中实现更改密码功能的最佳方法是什么?现在我正在使用这个:

$builder->add('password', 'repeated', array(
    'first_name' => 'New password',
    'second_name' => 'Confirm new password',
    'type' => 'password'
));
Run Code Online (Sandbox Code Playgroud)

出于安全原因,它还应包含当前密码检查.

注意:我没有使用FOSUserBundle.

jku*_*vic 50

从Symfony 2.3开始,您可以轻松使用UserPassword验证约束.

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;
}
Run Code Online (Sandbox Code Playgroud)

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';
    }
}
Run Code Online (Sandbox Code Playgroud)

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(),
      ));      
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @jkucharovic 这对我来说很好用。但是当我的密码是“保存密码”到浏览器时,对于这个表单,“旧密码”是预先填写的,如果密码更改不止一次,则预先填写的密码是错误的密码..那么我如何才能始终保持“旧密码”为空呢?试过 'array('always_empty' => false)' 但没有用。有什么解决办法吗? (2认同)

小智 8

您必须使用两个字段创建另一个模型:

  • 一个用于当前密码;
  • 另一个是新的.

或者像您的FOSUserBundle一样向您的用户模型添加非持久性属性(请参阅plainPassword属性).

因此,一旦您检查了当前密码和新密码是否有效,您将对新密码进行编码并用它替换旧密码.


Tay*_*lan 5

只需将其添加到您的表单类型:

$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',
));
Run Code Online (Sandbox Code Playgroud)

  • 使用时出现此错误->>> User 对象必须实现 UserInterface 接口。 (2认同)