2

我一直在寻找我的 Symfony2 验证选项。问题是这样的:

我有一个在 setPassword 方法中散列密码的 Member 类:

public function setPassword($password)
{
    $this->password = Encrypt::cryptPassword($password);
}

哈希是一个长字符串,无论原始输入如何都存在。

出于这个原因,这样的验证是没有用的:

 * @Assert\NotBlank()
 * @Assert\Length(
 *      min = "8",
 *      max = "15",
 *      minMessage = "Your password must be at least {{ limit }} characters",
 *      maxMessage = "Your password cannot be longer than {{ limit }} characters"
 * ) 

验证被触发,因为无论输入的有效性如何都创建了哈希字符串。

我看着尝试 getter 验证,但这似乎也是一个死胡同,因为我真正想要验证的是 setPassword() 的原始输入,并且在 setPassword 创建哈希值之后获取哈希值不是有帮助。

与现有的验证组件一起使用的推荐方法是什么,可以让我验证原始用户输入?

更新

虽然我接受了答案,但它并不真正可行。它确实使我专注于生命周期回调系统,这可能是解决方案的一部分。

鉴于当前的建议,一旦密码第一次被编码,任何时候你尝试编辑实体都会超过验证,因为散列密码当然不是输入,不能解密为原始输入。

我现在正在实体中尝试使用单独的属性,纯粹用于输入密码,以及使用验证组在某些情况下(新用户创建/密码更改)触发使用验证,而在其他情况下省略它案例。我确实计划使用 prePersist 和 preUpdate 回调来对密码进行编码。

仅作记录,这是在提供 REST api 的应用程序中使用的,以及用于选定功能的管理工具和 Web 前端。

4

1 回答 1

12

使用学说生命周期,永远不要修改 setter 的行为!

<?php

// ...

/**
 * @ORM\Entity()
 * @ORM\HasLifecycleCallbacks()
 */
class Member
{
    public function setPassword($password)
    {
        $this->password = $password;
    }

    /**
     * @ORM\PrePersist
     *
     * First time you save the entity
     */
    public function prePersist()
    {
        $this->password = Encrypt::cryptPassword($this->password);
    }
}

在此示例中,密码在您保存成员对象之前不会被编码,因此可以通过 assert 进行验证!

但是 Symfony2 安全性带有一个防火墙,可以加密成员的密码并简单地为您完成这项工作:

http://symfony.com/doc/current/book/security.html#encoding-the-user-s-password

于 2013-01-09T10:04:49.980 回答