【发布时间】:2014-08-06 20:32:50
【问题描述】:
我有以下值对象 (VO) Password。密码必须介于 6 到 20 个字符之间。但是由于我的UserMapper 在持久化实体之前对密码进行了哈希处理,所以我不知道我应该在这个 VO 中使用什么验证逻辑。
当UserMapper 返回User 时,密码是60 个字符长的散列形式。
这是否意味着我必须在我的价值对象中考虑这两种情况?目前它会抛出 InvalidArgumentException 异常,因为该值不会介于 6 到 20 个字符之间,而是 60 个字符长(散列)。
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;
}
}
【问题讨论】:
-
为什么
HashedPassword和Password之间没有区别? -
我对 DDD 还是比较陌生,但这意味着它们中的任何一个都将始终是
null。注册时HashedPassword为空,登录时Password为空。实体中可以有空值吗? -
我对 DDD 也没有经验,只是一个想法,因为哈希密码和密码基本上是不同的东西
-
另见 Openwall 的 PHP password hashing framework (PHPass)。它的便携性和强化了针对用户密码的一些常见攻击。编写框架 (SolarDesigner) 的人与编写 John The Ripper 并在 Password Hashing Competition 担任评委的人是同一个人。所以他对密码攻击略知一二。
标签: php validation hash domain-driven-design value-objects