Google没有太多解决方案(similar question but no answer)。
由于bcrypt每次都会生成一个新哈希,因此身份验证失败。我查看了代码(也许是自己扩展类),但它非常混乱(更喜欢本机解决方案)。如何将$bcrpt->verify()
与$identity->isValid()
一起使用?
编辑:目前,我已经将认证DbTable类子类化,并且它正在运行,但我非常怀疑它是否已经过优化/“完全正确”。仍在寻找“优雅”的解决方案。
答案 0 :(得分:15)
您可以使用:
Zend\Authentication\Adapter\DbTable\CallbackCheckAdapter
像这样:
use Zend\Authentication\Adapter\DbTable\CallbackCheckAdapter as AuthAdapter;
use Zend\Crypt\Password\Bcrypt;
$credentialValidationCallback = function($dbCredential, $requestCredential) {
return (new Bcrypt())->verify($requestCredential, $dbCredential);
};
$authAdapter = new AuthAdapter($dbAdapter, 'user', 'login', 'password', $credentialValidationCallback);
// ...
答案 1 :(得分:4)
正如你应该知道的那样,BCrypt使用盐来哈希。并且每次都会随机再次生成盐。如果您的数据库受到损害,这会大大增加查找所有密码的难度。因此,实际上,它每次都会生成一个新的哈希值。
我自己的解决方案是拥有自己的Zend\Authentication
适配器,它将从数据库中检索用户模型(使用用户名/电子邮件),然后调用$user->checkPassword($credential);
。该方法将获得Zend\Crypt\Password\Bcrypt
的实例。只需在给定密码上调用$bcrypt->verify()
,在用户模型中调用哈希。
答案 2 :(得分:1)
我这样做了(测试代码并且有效)..;
if ($request->isPost()) {
$form->setData($request->getPost());
if ($form->isValid()) {
$bcrypt = new Bcrypt();
$user = new User();
$user->exchangeArray($form->getData());
$password = $user->password;
$data = $this->getUserTable()->selectUser($user->username);
if (!$data)
{
echo 'user not found';
} else {
if ($bcrypt->verify($password, $data->hash)) {
$sm = $this->getServiceLocator();
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$authAdapter = new AuthAdapter(
$dbAdapter,
'cms_users',
'username',
'hash'
);
$authAdapter->setIdentity($user->username)
->setCredential($data->hash);
$result = $auth->authenticate($authAdapter);
echo $result->getIdentity() . "\n\n";
// do you thing on succes/failure
} else {
echo 'invalid password';
}
}
}
}