关于Symfony 2.1的这个问题
如何使用以下方法对用户密码进行编码:
$factory = $this->get('security.encoder_factory');
$user = new Acme\UserBundle\Entity\User();
$encoder = $factory->getEncoder($user);
$password = $encoder->encodePassword('ryanpass', $user->getSalt());
$user->setPassword($password);
基础配置:
# app/config/security.yml
security:
# ...
encoders:
Acme\UserBundle\Entity\User: sha512
在二传手模型中:
class User implements UserInterface, \Serializable
{
public function setPassword($password)
{
$this->password = $password;
}
}
我认为加密密码的过程必须按模型处理。 如何在模型中使用标准编码器工厂?
答案 0 :(得分:11)
虽然我同意@Vadim您不应该将业务逻辑泄漏到您的模型中,但我会小心推迟明文密码的散列,直到prePersist
事件,例如,除非您致电{在persist
之后{1}}和flush
。在此期间setPassword
调用将返回明文字符串,除非您将其存储在单独的字段中,这可能会产生严重后果。理想情况下,明文密码应在应用程序的生命周期内尽可能短的时间内存在。
我建议使用服务层,其中“用户管理器”提供常见任务的界面,这样您即使是暂时也不需要污染密码属性:
getPassword
在您的注册表单提交控制器中,例如:
class UserManager
{
// ...
public function __construct(EncoderFactoryInterface $encoderFactory)
{
// $encoderFactory is injected by the DIC as requested by your service configuration
// ...
}
public function setUserPassword(UserInterface $user, $plaintextPassword)
{
$hash = $this->encoderFactory->getEncoder($user)->encodePassword($plaintextPassword, null);
$user->setPassword($hash);
}
// ...
}
答案 1 :(得分:3)
实体包含数据,而不是处理它。如果要更改实体的数据,可以创建事件侦听器并在持久性之前执行操作。从官方文档中查看How to Register Event Listeners and Subscribers。
您还可以查看FosUserBundle及其用户管理。
因此,主要思想是将普通密码从表单传递给用户实体,并在使用事件监听器进行persitence之前对其进行编码。