1

到目前为止,我已经以纯文本形式存储了所有密码,因为该站点尚未上线,我决定等待新密码 api

我有此代码用于纯文本密码:

<?php
$dbAdapter = Zend_Db_Table::getDefaultAdapter();
$authAdapter = new Zend_Auth_Adapter_DbTable($dbAdapter);

$authAdapter->setTableName('account')
    ->setIdentityColumn('account_id')
    ->setCredentialColumn('account_password');

// Get our authentication adapter and check credentials
$adapter = $authAdapter;
$adapter->setIdentity($values['account_id']);
$adapter->setCredential($values['password']);

$auth = Zend_Auth::getInstance();
$result = $auth->authenticate($adapter);
if ($result->isValid()) {
    $user = $adapter->getResultRowObject();
    $auth->getStorage()->write($user);
    return true;
}
return false;

根据文档,我应该实现自己的适配器,并且可能只是更改以使用 password_verify()。

我在这里错过了一切如何协同工作的大图。

我的问题是:

  1. 我应该修改女巫对象吗?$authAdaper或者$auth

任何高级(或低级:D)示例代码将不胜感激。

最好的亚当

4

2 回答 2

1

如果您希望通过添加password_hash加密来修改身份验证的操作方式,那么您需要在PHP.

由于您仍希望使用数据库身份验证,我认为将其重新创建为新适配器将是矫枉过正。但是,您可以扩展当前的数据库适配器,例如:

class My_Auth_Adapter_DbTable extends Zend_Auth_Adapter_DbTable
{
  public function setCredential($credential)
  {
    $this->_credential = password_hash($credential);
    return $this;
  }
}

这意味着提供给适配器的任何密码都将始终使用该password_hash函数进行加密。

然而,这可以通过在调用setCredential.

$options  = array('salt' => $config->passwordSalt);
$hashPassword = password_hash($plainTextPassword, PASSWORD_BCRYPT, $options);
$adpater->setCredential($hashPassword);

此方法将允许您在传递给适配器之前修改可选参数。

最后,值得一提的是,该setCredentialTreatment方法通常用于提供密码加密,这是在 SQL 语句中执行的(这意味着您需要使用 MySQL 命令而不是password_hash)。

$authAdapter->setTableName('user')
      ->setIdentityColumn('email')
      ->setCredentialColumn('password')
      ->setCredentialTreatment(sprintf("MD5(CONCAT(?,'%s'))", $config->passwordSalt));
于 2013-07-03T10:28:03.947 回答
0

创建的password_hash()哈希需要通过 ̀password_verify()` 进行比较,因为相同密码的 2 个哈希并不总是相等(至少不使用 BCRYPT 或 ARGON2)。

<?php
$pass = 'foo';
var_dump(password_hash($pass, PASSWORD_BCRYPT) === password_hash($pass, PASSWORD_BCRYPT));
// bool(false)
var_dump(password_verify($pass, password_hash($pass, PASSWORD_BCRYPT)));
// bool(true)

有人(s7anley)做了一个Zend_Auth_Adapter_DbTable使用 password_verify() 的扩展,这里是(供参考):

<?php

class Base_Auth_Adapter_BcryptDbTable extends Zend_Auth_Adapter_DbTable
{
    /**
     * @inheritdoc
     */
    protected function _authenticateCreateSelect()
    {
        $dbSelect = clone $this->getDbSelect();
        $dbSelect->from($this->_tableName)
            ->where($this->_zendDb->quoteIdentifier($this->_identityColumn, true) . ' = ?', $this->_identity);

        return $dbSelect;
    }

    /**
     * @inheritdoc
     */
    protected function _authenticateValidateResult($resultIdentity)
    {
        $passwordCheck = password_verify($this->_credential, $resultIdentity[$this->_credentialColumn]);

        if (!$passwordCheck) {
            $this->_authenticateResultInfo['code'] = Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID;
            $this->_authenticateResultInfo['messages'][] = 'Supplied credential is invalid.';
            return $this->_authenticateCreateAuthResult();
        }

        $this->_resultRow = $resultIdentity;

        $this->_authenticateResultInfo['code'] = Zend_Auth_Result::SUCCESS;
        $this->_authenticateResultInfo['messages'][] =  'Authentication successful.';
        return $this->_authenticateCreateAuthResult();
    }
}

类名显示为“Bcrypt”,但它适用于任何支持的算法password_hash()

你可以这样使用它:

$authAdapter = new Base_Auth_Adapter_BcryptDbTable($databaseAdapter, 'users', 'login', 'password');
$authAdapter
    ->setIdentity('my_username')
    ->setCredential('my_password') // "clear" password
    // ->setCredentialTreatment(null) // Can't set any treatment on password (would be ignored)
;
// For any additional filtering of returned rows, use getDbSelect()
$authAdapter->getDbSelect()->where('active = "TRUE"');
于 2020-09-08T09:38:47.013 回答