Zend 2 Auth с Bcrypt?

У Google не так много решений (похожий вопрос, но нет ответа).

Поскольку bcrypt каждый раз генерирует новый хэш, аутентификация завершается ошибкой. Я просмотрел код (возможно, сам расширил класс), но он довольно беспорядочный (предпочел бы собственное решение). Как я могу использовать $bcrpt->verify() с $identity->isValid()?

Изменить: на данный момент я создал подкласс класса аутентификации DbTable, и он работает, но я очень сомневаюсь, что он оптимизирован / «полностью прав». Все еще ищу "элегантное" решение.


person Raekye    schedule 05.01.2013    source источник
comment
Действительно жаль, что ZF2 имеет оболочку Bcrypt, но не предоставляет адаптер аутентификации Brypt.   -  person markus    schedule 06.01.2013


Ответы (3)


Как вы должны знать, BCrypt хеширует с помощью соли. И эта соль каждый раз генерируется случайным образом. Это резко увеличивает сложность поиска всех паролей, если ваша база данных скомпрометирована. Таким образом, действительно, каждый раз будет генерироваться новый хеш.

Мое собственное решение проблемы, с которой вы столкнулись, заключается в наличии моего собственного адаптера Zend\Authentication, который извлекает модель пользователя из базы данных (используя имя пользователя/адрес электронной почты), а затем вызывает $user->checkPassword($credential);. Этот метод получит экземпляр Zend\Crypt\Password\Bcrypt. Который просто вызовет $bcrypt->verify() для заданного пароля и хэша в пользовательской модели.

person kokx    schedule 06.01.2013
comment
у меня тоже похожая проблема, @kokx как мы можем это сделать? пожалуйста, можете ли вы привести пример. - person Bineet Chaubey; 27.05.2013

Вы можете использовать:

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);
// ...
person B.Asselin    schedule 16.03.2014
comment
Отличное решение и очень аккуратно. Спасибо! - person MrNorm; 07.04.2015
comment
Он должен быть стандартным! - person Michael; 08.06.2016
comment
Работает как шарм! Нужен только обратный вызов. Я думаю, что это лучшее решение, поскольку вам больше нечего менять до вызова метода isValid. - person BoCyrill; 21.08.2016
comment
Это определенно правильный путь при использовании службы аутентификации ZF. Конечно, нет единственно правильного пути, но его следует отнести к стандартному пути ZF. - person Nuxwin; 14.02.2019

Я сделал это так (тестовый код, и он работает)..;

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';
                    }
                }
            }
        }
person directory    schedule 25.03.2014
comment
Прежде всего, вы выполняете дополнительный вызов БД, проверяете введенный пользователем пароль с помощью хэша из первого вызова БД, затем используете хэш из первого вызова БД для аутентификации с помощью хэша, который находится в БД, используя второй вызов БД. Это сработает, но это неправильный путь. Я думаю, что решение, предоставленное @bigBen, является правильным. - person Evren Yurtesen; 23.03.2016