Php 可以散列或原始的密码值对象

Php 可以散列或原始的密码值对象,php,validation,hash,domain-driven-design,value-objects,Php,Validation,Hash,Domain Driven Design,Value Objects,我得到了以下值对象(VO)Password。密码必须介于6到20个字符之间。但是,由于我的UserMapper在持久化实体之前正在散列密码,我不知道在这个VO中应该有什么验证逻辑 当UserMapper返回一个User时,密码是60个字符长的散列形式 这是否意味着我必须在我的价值对象中考虑这两种情况?目前,它将抛出一个InvalidArgumentException异常,因为该值的长度不是6到20个字符,而是60个字符(散列) 名称空间模型\值\用户; 使用\InvalidArgumentExc

我得到了以下值对象(VO)
Password
。密码必须介于6到20个字符之间。但是,由于我的
UserMapper
在持久化实体之前正在散列密码,我不知道在这个VO中应该有什么验证逻辑

UserMapper
返回一个
User
时,密码是60个字符长的散列形式

这是否意味着我必须在我的价值对象中考虑这两种情况?目前,它将抛出一个
InvalidArgumentException
异常,因为该值的长度不是6到20个字符,而是60个字符(散列)

名称空间模型\值\用户;
使用\InvalidArgumentException;
类密码
{
私人$min=6;
私人$max=20;
私人$password;
公共函数构造($password)
{
如果(是字符串($password)&&!空($password)){
$length=$this->stringLength($password);
如果($length>=$this->min&&$length max){
$this->password=$password;
}
}否则{
抛出新的InvalidArgumentException(sprintf(“%s”必须是从%s到%s个字符的字符串。“,”方法“,$this->min,$this->max”);
}
}
公共函数
{
返回$this->password;
}
私有函数stringLength($string)
{
$encoding=mb_detect_encoding($string);
$length=mb_strlen($string,$encoding);
返回$length;
}
}

客户端密码验证的长度可以在包含密码字符串项的文本框中。 之后,应该将其视为安全密码(如果密码存储接受)

之后,您不应设置或从密码存储中获取密码,而应要求存储为您验证密码


因此,我认为你检查密码强度已经太迟了,除非你能早点做。

我同意@kingkero在上面的评论:让这两个不同的类


我建议只能通过
Password
上的工厂方法创建
HashedPassword
(可能使用作为参数提供的
PasswordHashAlgorithm
服务),在
Password
验证输入后,该方法将用于创建哈希密码。只有
HashedPassword
s被持久化。

为什么不区分
HashedPassword
Password
?我对DDD还是比较陌生,但这意味着它们中的任何一个在任何时候都是
null
。注册
HashedPassword
时为空,登录
Password时为空。实体中有空值可以吗?我对DDD也没有经验,只是一个想法,因为散列密码和密码基本上是不同的东西,所以请参阅Openwall的(PHPass)。它的可移植性强,可抵御多种常见的用户密码攻击。编写框架的人(SolarDesigner)就是编写框架并担任该框架法官的那个人。所以他知道一些关于密码攻击的事情。然后你应该建立一个安全的(https)连接。我的
用户
实体现在包含
密码
密码哈希
。为了散列密码(在我的
UserMapper
中),我使用了可靠的内置PHP函数
password\u hash()
。我有一个
UserFactory
,它有一个
build()
方法来构建完整的用户对象(使用从
UserMapper
返回的数据)和
buildFresh()
来构建新的用户对象,并且仍然需要持久化(它保持
Id
PasswordHash
为空,并使用
Password
)。我已经接受了你的答案,但我对你详细阐述答案的方式有点困惑。那么你能详细说明一下吗?只有我的
密码
包含验证逻辑,
密码哈希
不包含验证逻辑,因为实际上无法验证哈希本身。我只能检查哈希是否为pr操作长度(60个字符)。很抱歉,我没有完全理解你的问题。为什么你的
用户
包含
密码
密码哈希
?一个
用户
不只需要
密码
?因为我的VO包含验证逻辑。和
密码
(干净的文本)与
PasswordHash
(散列)不同。注册新用户时使用
Password
,从我的数据库中检索时使用
PasswordHash
,因为我的数据库中只存储散列密码。对不起,我的意思是“一个
用户
是否只需要
散列密码?”。我认为没有必要向
用户添加
密码
密码
将在构建时验证输入,如果您随后将
密码
传递给
用户工厂
,工厂可以对验证后的密码进行散列,并使用散列后的密码创建
用户
namespace Models\Values\User;

use \InvalidArgumentException;

class Password
{
    private $min = 6;
    private $max = 20;

    private $password;

    public function __construct($password)
    {
        if (is_string($password) && !empty($password)) {
            $length = $this->stringLength($password);

            if ($length >= $this->min && $length <= $this->max) {
                $this->password = $password;
            }
        } else {
            throw new InvalidArgumentException(sprintf('%s must be a string from %s to %s characters.', __METHOD__, $this->min, $this->max));
        }
    }

    public function __toString()
    {
        return $this->password;
    }

    private function stringLength($string)
    {
        $encoding = mb_detect_encoding($string);
        $length   = mb_strlen($string, $encoding);

        return $length;
    }
}