我正在尝试使用令牌来实现提醒密码。
我创建了表单:
class RemindPasswordType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('email', EmailType::class, [
'label' => 'label.email'
]);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => User::class,
'validation_groups' => [
'remind_password'
]
]);
}
}
用户实体:
class User implements UserInterface
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string")
* @Assert\NotBlank(message="default.not_blank")
* @Assert\Email(message="default.email")
* @AcmeAssert\ExistentEmail(groups= {"remind_password"})
*/
private $email;
/**
* @ORM\Column(type="string", nullable=true)
*/
private $remindToken;
}
ExistentEmailValidator:
class ExistentEmailValidator extends ConstraintValidator
{
private $userRepository;
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}
public function validate($value, Constraint $constraint)
{
if (!$this->userRepository->findUserByEmail($value)) {
$this->context->buildViolation($constraint->message)->addViolation();
}
}
问题:
$ form-> getData()返回仅包含电子邮件字段的User对象。我被迫在Controller中再次调用findAccountByEmail方法。我想防止这种情况。实际上,我想知道我是否应该在User的实体类中使用validation_group。实施提醒密码的正确方法是什么?
答案 0 :(得分:0)
没有适当安全的方式来提醒某人密码本身。普通密码永远不能从数据库中获取(实际上,它不是在Symfony中)。数据库仅存储散列,该散列允许单向检查潜在密码。而且我什至认为symfony采取了一些额外的措施来防止在加载用户对象时使用或加载密码。即使在创建用户时,纯密码字段也会在之后清除,以防止泄漏。
密码重置是正确的方法
一种实现方法是允许用户使用通过链接发送电子邮件的令牌来更改密码。当单击链接并且get参数令牌与数据库中的令牌相同时,那么我们允许他无需登录即可更改密码
另一种方法是使用非常个人的问题,如果回答正确,再次允许他定义新密码而无需登录。
或者您选择执行上述操作之一,但自己创建一个密码,然后通过电子邮件将其发送给用户,而不是让用户提供自己的密码
我建议检查FOS User Bundle的代码以检查其工作方式,并进行相应修改以适合您自己的规范