2012-02-03 14 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の検証制約を簡単に使用できます。

アクメ\ 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; 
} 

アクメ\ 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'; 
    } 
} 

アクメ\ 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

は、ログインせずにパスワードを変更することが可能ですか? –

+0

@AjayPatelいいえ、それはできません。現在の認証済みユーザの 'UserPasswordValidator' [セキュリティコンテキストを使用](https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Security/Core/Validator/Constraints/UserPasswordValidator.php#L37) – jkucharovic

+0

大丈夫、問題解決には問題ありません。 –

7

は、次の2つのフィールドを持つ別のモデルを作成するために、どちらかがあります:現在のパスワードの

  • 1。
  • ともう1つは新しいものです。

また、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', 
)); 
関連する問題