2012-02-03 39 views
19

Cách tốt nhất để thực hiện chức năng thay đổi mật khẩu trong Symfony2 là gì? Bây giờ tôi đang sử dụng này:Thực hiện thay đổi mật khẩu trong Symfony2

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

Cũng cần contait kiểm tra mật khẩu hiện tại vì lý do an ninh.

Lưu ý: Tôi không sử dụng FOSUserBundle.

Trả lời

43

Vì Symfony 2.3 bạn có thể dễ dàng sử dụng ràng buộc xác thực UserPassword.

Acme \ UserBundle \ Mẫu \ mẫu \ 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 \ Mẫu \ 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 \ khiển \ 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

là nó có thể thay đổi mật khẩu mà không cần đăng nhập? –

+0

@AjayPatel không, không thể. 'UserPasswordValidator' [sử dụng ngữ cảnh bảo mật] (https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Security/Core/Validator/Constraints/UserPasswordValidator.php#L37) của người dùng được xác thực hiện tại – jkucharovic

+0

được rồi, giải pháp không thành vấn đề. –

7

Bạn phải hoặc là tạo ra một mô hình khác với hai lĩnh vực:

  • một cho mật khẩu hiện hành;
  • và loại kia cho hình mới.

Hoặc thêm thuộc tính không tồn tại vào kiểu người dùng của bạn như FOSUserBundle (xem thuộc tính plainPassword).

Vì vậy, khi bạn đã kiểm tra cả mật khẩu hiện tại và mật khẩu mới đều hợp lệ, bạn mã hóa mật khẩu mới và thay thế mật khẩu cũ bằng mật khẩu mới.

1

Bạn không thể nhận mật khẩu cũ từ Người dùng trước biểu mẫu ràng buộc?

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

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

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

tôi sử dụng một hành động từ điều khiển của tôi:

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

Chỉ cần thêm này thành một loại hình của bạn:

$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', 
)); 
Các vấn đề liên quan