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_DbTablepassword_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 に答える