forms - granted - symfony login roles
Implementar cambio de contraseƱa en Symfony2 (5)
¿Cuál es la mejor manera de implementar la funcionalidad de cambio de contraseña en Symfony2? Ahora mismo estoy usando esto:
$builder->add(''password'', ''repeated'', array(
''first_name'' => ''New password'',
''second_name'' => ''Confirm new password'',
''type'' => ''password''
));
También debe contener la verificación de la contraseña actual por razones de seguridad.
Nota : no estoy usando FOSUserBundle
.
¿No puede obtener una contraseña antigua del usuario antes de enlazar el formulario?
// in action:
$oldpassword = $user->getPassword();
if ($request->getMethod() == ''POST'')
{
$form->bindRequest($request);
if ($form->isValid())
{
// check password here (by hashing new one)
Desde Symfony 2.3 puedes usar fácilmente la restricción de validación de 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;
}
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'';
}
}
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(),
));
}
}
Solo agregue esto a su tipo de formulario:
$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'',
));
Tienes que crear otro modelo con dos campos:
- uno para la contraseña actual;
- y el otro por el nuevo.
O agregue una propiedad no persistente a su modelo de usuario como lo hace FOSUserBundle (vea la propiedad plainPassword
).
Por lo tanto, una vez que haya verificado que la contraseña actual y la nueva son válidas, codifique la nueva contraseña y reemplace la antigua con esta.
Utilizo una acción desde mi controlador:
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(
));
}