Symfony3表单更改密码错误@SecurityAssert \ UserPassword

时间:2018-02-01 19:08:23

标签: symfony symfony-3.3

我在更改密码的典型表单上遇到问题,我首先要将密码放入当前密码。

理论非常简单,并在symfony doc中进行了解释,但它给出了一个错误,就像当前密码不正确一样

我的模特:

namespace BackendBundle\Form\Model;

use Symfony\Component\Security\Core\Validator\Constraints as SecurityAssert;
use Symfony\Component\Validator\Constraints as Assert;

class ChangePassword
{
/**
 * @SecurityAssert\UserPassword(
 *     message = "Error al poner la contraseña actual"
 * )
 */
 protected $oldPassword;

/**
 * @Assert\Length(
 *     min = 6,
 *     minMessage = "El password tiene que tener al menos 6 caracteres"
 * )
 */
 protected $password;


   /////
public function getOldPassword() {
    return $this->oldPassword;
}

public function setOldPassword($oldPassword) {
    $this->oldPassword = $oldPassword;
}
  /////
public function getPassword() {
    return $this->oldPassword;
}

public function setPassword($oldPassword) {
    $this->oldPassword = $oldPassword;
}
}

fomType:

->add('oldPassword', PasswordType::class, array(
                'label' => 'Ponga su password actual',
                'mapped' => false,
                ))
->add('password', RepeatedType::class, array(
                "required" => "required",
                'type' => PasswordType::class,
                'invalid_message' => 'Los dos password deben coincidir',
                'first_options' => array('label' => 'Password nuevo', "attr" 
=> array("class" => "form-password form-control")),
                'second_options' => array('label' => 'Repita el Password nuevo', "attr" => array("class" => "form-password form-control"))
                    )
            )

除了控制器创建带有表单的视图然后收集新密码的数据等之外,其他一切都必须完成(我认为),但正如我所说,我发送了无效字段的错误,检查密码和我不知道是不是因为密码我保持加密 我的security.yml我把它作为

encoders:
    BackendBundle\Entity\Users:
        algorithm: bcrypt
        cost: 6

我的行动控制器:

   public function passAction(Request $request) {
    $changePasswordModel = new ChangePassword();
    $form = $this->createForm(ChangePasswordType::class, $changePasswordModel);

    $form->handleRequest($request);

    if ($form->isSubmitted()) {

        if ($form->isValid()) {

            $user = $this->getUser(); //metemos como id la del usuario sacado de su sesion
            $encoder = $this->container->get('security.encoder_factory')->getEncoder($user);
            $password = $encoder->encodePassword($changePasswordModel->getPassword(), $user->getSalt());
            $user->setPassword($password);
            $em->persist($user);
            $flush = $em->flush();
            if ($flush === null) {
                $this->session->getFlashBag()->add('success', 'El usuario se ha editado correctamente');
                return $this->redirectToRoute("others_show"); //redirigimos la pagina si se incluido correctamete
            } else {
                $this->session->getFlashBag()->add('warning', 'Error al editar el password');
            }
        } else {
            dump($form->getErrors());
            $this->session->getFlashBag()->add('warning', 'El password no se ha editado por un error en el formulario !');
        }
    }

    return $this->render('BackendBundle:Others:editPass.html.twig', array(
                'form' => $form->createView(),
    ));
}

它告诉我表单不正确,因为旧密码不正确。可能有什么不对?

3 个答案:

答案 0 :(得分:1)

您无需自行检查旧密码的有效性。当你致电form->isValid()时,Symfony会为你做这件事。所以你可以放弃这个:

    $currentPassword = $form->get("oldPassword")->getData();

    $encoder = $this->container->get('security.encoder_factory')->getEncoder($user);
    $isValid = $encoder->isPasswordValid($user->getPassword(), $currentPassword, $user->getSalt());
    $encoderService = $this->container->get('security.password_encoder');
    $match = $encoderService->isPasswordValid($user, $currentPassword);
    dump($match);

相反,启动你的控制器:

public function passAction(Request $request) {

    $changePasswordModel = new PasswordChange();
    $form = $this->createForm(PasswordChangeType::class, $changePasswordModel);

    $form->handleRequest($request);

    if ($form->isSubmitted() && $form->isValid()) { // will check if old password was valid
        $user = $this->getUser(); //metemos como id la del usuario sacado de su sesion
        $encoder = $this->container->get('security.encoder_factory')->getEncoder($user);
        $password = $encoder->encodePassword($changePasswordModel->getPassword(), $user->getSalt());
        $user->setPassword($password);
        // go on with saving $user to database

答案 1 :(得分:0)

非常感谢@Spunc 的帮助,我终于让它正常工作了; - )

我提供了正确的完整代码,以防其他用户遇到问题。再次感谢

<强> passControler

namespace BackendBundle\Form\Model;

use Symfony\Component\Security\Core\Validator\Constraints as SecurityAssert;
use Symfony\Component\Validator\Constraints as Assert;

class ChangePassword {

/**
 * @SecurityAssert\UserPassword(
 *     message = "Error al poner la contraseña actual"
 * )
 */
protected $oldPassword;

/**
 * @Assert\Length(
 *     min = 6,
 *     minMessage = "El password tiene que tener al menos 6 caracteres"
 * )
 */
protected $password;


public function getOldPassword() {
    return $this->oldPassword;
}

public function setOldPassword($oldPassword) {
    $this->oldPassword = $oldPassword;
    return $this;
}


public function getPassword() {
    return $this->password;
}

public function setPassword($password) {
    $this->password = $password;
    return $this;
}

}

模型 ChangePassword

namespace BackendBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;

class ChangePasswordType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{

    $builder
                ->add('oldPassword', PasswordType::class, array(
                'label' => 'Ponga su password actual',
                ))
            ->add('password', RepeatedType::class, array(
                "required" => "required",
                'type' => PasswordType::class,
                'invalid_message' => 'Los dos password deben coincidir',
                'first_options' => array('label' => 'Password nuevo', "attr" => array("class" => "form-password form-control")),
                'second_options' => array('label' => 'Repita el Password nuevo', "attr" => array("class" => "form-password form-control"))
                    )
            )
    ;
}

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => 'Acme\UserBundle\Form\Model\ChangePassword',
    ));
}

public function getName()
{
    return 'change_passwd';
}
}

<强> ChangePasswordType

class WebFieldType(models.Model):
    WEBFIELD_CHOICES = ( ('FACEBOOK', 'fb'), ('INSTAGRAM', 'Insta') )
    webfield_type = models.CharField(null=True, blank=True, max_length=30, choices=WEBFIELD_CHOICES)
    def __unicode__(self):
        return '{}'.format(self.webfield_type)


class WebTokens(models.Model):
    token_name = models.TextField()
    web_field_type = models.ManyToManyField(WebFieldType)

    def __unicode__(self):
        return '{}-{}'.format(self.token_name,self.web_field_type )

答案 2 :(得分:0)

我对“ @SecurityAssert \ UserPassword”断言存在相同的问题。我以

形式开始
"mapped" => false

解决了我的问题。非常感谢。仅是未来问题访客的一句话。密码编码器的签名已更改。

在Symfony 4.4中,这样的设置将正确编码新密码

$user->setPassword(
    $passwordEncoder->encodePassword( $user,
    $changePasswordModel->getPassword()
) );