1
我已經實現了一個簡單的密碼更改算法。下面的代碼:學說 - preUpdate事件訂閱者根本不被解僱
public function postChangePasswordAction(Request $request, $username)
{
$em = $this->getDoctrine()->getManager();
$user = $em->getRepository("TskUserBundle:User")->findOneByUsername($username);
if(!$user)
{
throw $this->createNotFoundException("User not found!");
}
$form = $this->createPasswordChangeForm();
$form->handleRequest($request);
$old_password = $form->get('old_password')->getData();
$new_password = $form->get("new_password")->getData();
if($form->isValid())
{
$old_password_encoded = $this->get("tsk_encoder")->encode($user, $old_password, $user->getSalt());
if($old_password_encoded == $user->getPassword())
{
$user->setPlainPassword($new_password);
$user->setFirstname("rofa");
$em->flush();
return $this->redirect($this->generateUrl("tsk_user_profile", array("username"=>$user->getUsername())));
} else { return new Response($old_password_encoded."\n".$user->getPassword());}
}
return $this->render("TskUserBundle:User:change_password.html.twig", array("username" => $user->getUsername(), "form"=>$form->createView()));
}
我User
實體是:
<?php
namespace Tsk\UserBundle\Entity;
use Symfony\Component\Security\Core\User\AdvancedUserInterface;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Validator\Constraints as Assert;
/**
* @ORM\Entity(repositoryClass="Tsk\UserBundle\Repository\UserRepository")
* @ORM\Table(name="users")
* @ORM\HasLifecycleCallbacks
* @Assert\GroupSequence({"FormCreate", "FormEdit", "User"})
*/
class User implements AdvancedUserInterface, \Serializable
{
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\Column(type="string", length=25, unique=true)
* @Assert\NotBlank(groups={"FormEdit", "FormCreate"})
*/
protected $username;
/**
* @Assert\NotBlank(groups={"FormCreate"})
* @Assert\Length(min="4", minMessage="Password must be 4 characters at least", groups={"FormCreate"})
*/
protected $plain_password;
/**
* @ORM\Column(type="string", length=128)
* @Assert\NotBlank
*/
protected $password;
/**
* @ORM\Column(type="string", length=50, unique=true)
* @Assert\Email(groups={"FormEdit", "FormCreate"});
*/
protected $email;
/**
* @ORM\Column(type="boolean")
*/
protected $is_active;
/**
* @ORM\Column(type="string", length=59)
* @Assert\NotBlank(groups={"FormEdit", "FormCreate"})
*/
protected $firstname;
/**
* @ORM\Column(type="string", length=59)
* @Assert\NotBlank(groups={"FormEdit", "FormCreate"})
*/
protected $lastname;
/**
* @ORM\ManyToMany(targetEntity="Role", inversedBy="users", cascade={"persist"})
* @Assert\NotBlank
*/
protected $roles;
/**
* @ORM\Column(type="string", length=50)
*/
protected $salt;
public function __construct()
{
$this->roles = new ArrayCollection();
$this->salt = md5(uniqid(null, true));
}
/**
* @ORM\PrePersist
*/
public function setIsActiveValue()
{
$this->setIsActive(true);
}
public function getPlainPassword()
{
return $this->plain_password;
}
public function setPlainPassword($plain_password)
{
$this->plain_password = $plain_password;
return $this;
}
public function setPassword($password)
{
$this->password = $password;
return $this;
}
public function isAccountNonExpired()
{
return true;
}
public function isAccountNonLocked()
{
return true;
}
public function isCredentialsNonExpired()
{
return true;
}
public function isEnabled()
{
return $this->getIsActive();
}
public function getRoles()
{
return $this->roles->toArray();
}
public function getPassword()
{
return $this->password;
}
public function getSalt()
{
return $this->salt;
}
public function getUsername()
{
return $this->username;
}
/**
* Removes sensitive data from the user.
*
* This is important if, at any given point, sensitive information like
* the plain-text password is stored on this object.
*/
public function eraseCredentials()
{
}
public function serialize()
{
return serialize(array($this->getUsername()));
}
public function unserialize($serialized)
{
list($this->username) = unserialize($serialized);
}
public function getId()
{
return $this->id;
}
public function setUsername($username)
{
$this->username = $username;
return $this;
}
public function setEmail($email)
{
$this->email = $email;
return $this;
}
public function getEmail()
{
return $this->email;
}
public function setIsActive($isActive)
{
$this->is_active = $isActive;
return $this;
}
public function getIsActive()
{
return $this->is_active;
}
public function setFirstname($firstname)
{
$this->firstname = $firstname;
return $this;
}
public function getFirstname()
{
return $this->firstname;
}
public function setLastname($lastname)
{
$this->lastname = $lastname;
return $this;
}
public function getLastname()
{
return $this->lastname;
}
public function addRole(Role $roles)
{
$this->roles[] = $roles;
return $this;
}
public function removeRole(Role $roles)
{
$this->roles->removeElement($roles);
}
}
我有兩個prePersist
和preUpdate
事件訂戶。當我創建一個新用戶時,它通常會被解僱。但是,當我只更改密碼它根本不起作用。 (注意plain_password
屬性是一個虛擬的沒有得到保存在數據庫中。)
下面的代碼:
<?php
namespace Tsk\UserBundle\EventSubscriber;
use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Tsk\UserBundle\Entity\User;
use Tsk\UserBundle\Utils\Encoder;
class EncoderSubscriber implements EventSubscriber
{
protected $encoder;
public function __construct(Encoder $ef)
{
$this->encoder = $ef;
}
/**
* Returns an array of events this subscriber wants to listen to.
*/
public function getSubscribedEvents()
{
return array(
'preUpdate',
'prePersist',
);
}
public function preUpdate(LifecycleEventArgs $args)
{
$this->encode($args);
}
public function prePersist(LifecycleEventArgs $args)
{
$this->encode($args);
}
protected function encode(LifecycleEventArgs $args)
{
$user = $args->getEntity();
if($user instanceof User)
{
$encodedPassword = ($this->encoder->encode($user, $user->getPlainPassword(), $user->getSalt()));
$user->setPassword($encodedPassword);
}
}
}
?>
在您的postChangePasswordAction上,您需要在調用刷新之前保留您的$ user對象。 –
@joaoalves我試過了。不幸的是,它不能解決問題。 –
你確定postChangePasswordAction在密碼更改時被調用嗎? – George