Рассмотрим следующий класс
class User
{
protected $password;
public function setPassword($password)
{
$this->password = $password;
return $this;
}
public function getPassword()
{
return $this->password;
}
}
Я хочу применить bcrypt к паролю, используя Zend\Crypt\Password\Bcrypt
в объекте пользователя, так как это создает зависимость, я хочу знать, как правильно с этим справляться, я могу подумать о нескольких подходах, чтобы сделать эту работу, позвольте мне прояснить
Подход 1 Здесь мы создаем экземпляр класса внутри метода и применяем необходимые изменения.
class User
{
protected $password;
public function setPassword($password)
{
$bcrypt = new Bcrypt();
$this->password = $bcrypt->create($password);
return $this;
}
public function getPassword()
{
return $this->password;
}
public function verifyPassword($password)
{
$bcrypt = new Bcrypt();
return $bcrypt->verify($password, $this->getPassword());
}
}
Насколько я понимаю, это не рекомендуемый подход, так как я вижу две проблемы здесь
Я могу решить проблему-1 путем создания экземпляра Bcrypt () один раз в конструкторе классов и использовать его всякий раз, когда это необходимо, однако это не решает проблему-2
Подход 2: Переместить объект Bcrypt из пользовательского класса и внедрить его при установке пароля
class User
{
protected $password;
public function setPassword($password)
{
$this->password = $password;
return $this;
}
public function getPassword()
{
return $this->password;
}
}
// Init Bcrypt
$bcrypt = new Bcrypt;
// Instantiate user object and create a password
$user = new User;
$user->setPassword($bcrypt->create($password));
// Verify user password
if ($bcrypt->verify($password, $user->getPassword())) {
// Password is verified
}
Каков наилучший способ об этом?
Благодарю.
А может быть, вы можете просто создать класс Password и перенести туда эту логику?
Вы можете сделать что-то вроде этого:
class Password
{
private $password;
public __construct($password)
{
$this->password = $password;
}
public crypt(Zend_Crypt_Password_PasswordInterface $crypt)
{
$this->password = $crypt->create($password);
}
}
или использовать декоратор.
Оба решения дают вам возможность расширить ваш код.
Вместо Zend_Crypt_Password_PasswordInterface
Вы также можете использовать свой собственный обертка. Это было бы ИМХО даже лучшим решением.
И тогда вы можете установить пароль для конкретного пользователя, и ему все равно, был ли он зашифрован, хеширован или что-то еще:
class User
{
private $password;
public function changePassword(Password $password)
{
$this->password = $password;
}
}
Я думаю, что первый подход лучше, потому что его скрывать использование bcrypt в классе User.
Я не думаю, что другой программист должен иметь в виду, что он должен использовать, например, $bcrypt->verify
при работе с User
учебный класс.