2012-02-03 58 views
19

在Symfony2中實現更改密碼功能的最佳方式是什麼? 現在,我使用這個:在Symfony2中實現更改密碼

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

還應contait出於安全原因,當前密碼檢查。我不使用FOSUserBundle

回答

43

由於Symfony 2.3可以很容易地使用UserPassword驗證約束。

的Acme \ UserBundle \表格\模型\ 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 \表格\ 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 \控制器\ 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

是有可能沒有登錄更改密碼? – 2014-02-13 10:49:48

+0

@AjayPatel不,這是不可能的。當前經過身份驗證的用戶的UserPasswordValidator [使用安全上下文](https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Security/Core/Validator/Constraints/UserPasswordValidator.php#L37) – jkucharovic 2014-02-13 11:03:41

+0

好吧,解決方案沒問題。 – 2014-02-14 05:34:42

7

你必須要麼創建另一個模型有兩個字段:

  • 一個當前密碼;
  • 和另一個爲新的。

或者像FOSUserBundle那樣向您的用戶模型添加非持久屬性(請參閱plainPassword屬性)。

因此,一旦您檢查當前和新密碼都有效,您將編碼新密碼並用它替換舊密碼。

1

不能在綁定表單之前從用戶那裏獲取舊密碼嗎?

// in action: 
$oldpassword = $user->getPassword(); 

if ($request->getMethod() == 'POST') 
     { 
      $form->bindRequest($request); 

      if ($form->isValid()) 
      { 
       // check password here (by hashing new one) 
3

我用一個動作從我的控制器:

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(

    )); 
} 
3

只需添加到您的表單類型:

$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', 
));