在Symfony2中实施更改密码功能的最佳方法是什么? 现在我正在使用它:
$builder->add('password', 'repeated', array(
'first_name' => 'New password',
'second_name' => 'Confirm new password',
'type' => 'password'
));
出于安全原因,它还应包含当前的密码检查。
注意:我没有使用FOSUserBundle
。
答案 0 :(得分:50)
从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(),
));
}
}
答案 1 :(得分:8)
您必须使用两个字段创建另一个模型:
或者像FOSUserBundle一样向您的用户模型添加非持久性属性(请参阅plainPassword
属性)。
因此,一旦您检查了当前密码和新密码是否有效,您可以对新密码进行编码并用旧密码替换旧密码。
答案 2 :(得分: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',
));
答案 3 :(得分:4)
我使用来自我的控制器的动作:
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(
));
}
答案 4 :(得分:1)
在绑定表单之前,您是否无法从用户获取旧密码?
// in action:
$oldpassword = $user->getPassword();
if ($request->getMethod() == 'POST')
{
$form->bindRequest($request);
if ($form->isValid())
{
// check password here (by hashing new one)