php – 在表单类型中使用Symfony2 UserPassword验证程序
我试图在表单中使用特定的验证器.
该表格是供用户重新定义他的密码,他还必须输入他当前的密码. 在我的形式: use SymfonyComponentSecurityCoreValidatorConstraintsUserPassword; 并且表单类型如下所示: /** * @param FormBuilderInterface $builder * @param array $options */ public function buildForm(FormBuilderInterface $builder,array $options) { $builder ->add('currentpassword','password',array('label'=>'Current password','mapped' => false,'constraints' => new UserPassword(array('message' => 'you wot m8?')),'required' => true )) ->add('password','repeated',array( 'first_name' => 'new','second_name' => 'confirm','type' => 'password','required' => true )) ; } 我知道在我的控制器中我可以获取数据表单,获取currentpassword值,调用security.encoder_factory等,但验证器看起来很方便. 我的问题是表单总是返回错误(这里:’你输了m8?’)就像我输入了错误的当前密码一样. 知道我做错了什么吗? 解决方法
我知道这个问题的答案会迟到几年,但是当我遇到同样的问题时,我想提出我的解决方案:
问题是我在用于FormMapping的$user实体和来自security.context的User之间存在连接. 请参阅以下内容:(PasswordChange – Controller) $username = $this->getUser()->getUsername(); $user = $this->getDoctrine()->getRepository("BlueChordCmsBaseBundle:User")->findOneBy(array("username"=>$username)); // Equal to $user = $this->getUser(); $form = $this->createForm(new ChangePasswordType(),$user); //ChangePasswordType equals the one 'thesearentthedroids' posted $form->handleRequest($request); if($request->getMethod() === "POST" && $form->isValid()) { $manager = $this->getDoctrine()->getManager(); $user->setPassword(password_hash($user->getPassword(),PASSWORD_BCRYPT)); [...] } return array(...); isValid()函数正在触发UserPassword Constraint Validator: public function validate($password,Constraint $constraint) { if (!$constraint instanceof UserPassword) { throw new UnexpectedTypeException($constraint,__NAMESPACE__.'UserPassword'); } $user = $this->tokenStorage->getToken()->getUser(); if (!$user instanceof UserInterface) { throw new ConstraintDefinitionException('The User object must implement the UserInterface interface.'); } $encoder = $this->encoderFactory->getEncoder($user); if (!$encoder->isPasswordValid($user->getPassword(),$password,$user->getSalt())) { $this->context->addViolation($constraint->message); } } 感兴趣的行是:if(!$encoder-> isPasswordValid($user-> getPassword(),$user-> getSalt())) 在我的情况下,$user-> getPassword()将我刚刚在表单中输入的新密码作为我的新密码. 奇怪的! 我的解决方案是将ChangePasswordType中的(新)密码字段与EntityMapping分离:参见 ->add('currentpassword','constraints' => new UserPassword())) ->add('password',array( 'mapped' => false,'type' => 'password','invalid_message' => 'The password fields must match.','required' => true,'first_options' => array('label' => 'Password'),'second_options' => array('label' => 'Repeat Password'),)) ->add('Send','submit') ->add('Reset','reset') 感兴趣的线是’mapped’=>假, 这样,在表单中输入的新密码将不会自动映射到给定的$user实体.相反,你现在需要从表单中获取它.看到 $form->handleRequest($request); if($request->getMethod() === "POST" && $form->isValid()) { $data = $form->getData(); $manager = $this->getDoctrine()->getManager(); $user->setPassword(password_hash($data->getPassword(),PASSWORD_BCRYPT)); $manager->persist($user); $manager->flush(); } 我无法完全理解问题的一些解决方法.如果有人可以解释数据库对象和security.context对象之间的连接,我很高兴听到它! (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |