4

谷歌没有太多的解决方案(类似的问题,但没有答案)。

因为 bcrypt 每次都会生成一个新的哈希,所以认证失败。我已经查看了代码(也许我自己扩展了类),但它非常混乱(更喜欢本机解决方案)。如何使用$bcrpt->verify()with $identity->isValid()

编辑:目前,我已经对身份验证 DbTable 类进行了子类化,并且它正在工作,但我非常怀疑它是否经过优化/“完全正确”。仍在寻找“优雅”的解决方案。

4

3 回答 3

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);
// ...
于 2014-03-16T15:07:53.770 回答
4

如您所知,BCrypt 使用盐进行散列。并且每次都会随机再次生成盐。如果您的数据库遭到破坏,这会大大增加查找所有密码的难度。因此,实际上,它每次都会生成一个新的散列。

对于您遇到的问题,我自己的解决方案是拥有自己的Zend\Authentication适配器,它将从数据库中检索用户模型(使用用户名/电子邮件),然后调用$user->checkPassword($credential);. 该方法将获得Zend\Crypt\Password\Bcrypt. 这将简单地调用$bcrypt->verify()给定的密码和用户模型中的哈希。

于 2013-01-06T11:25:47.967 回答
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';
                    }
                }
            }
        }
于 2014-03-25T09:38:10.560 回答