Yii 2如何在登录过程中获得并使用salt和cost来验证密码哈希


How Yii 2 get and use salt and cost to verify the password hash during the login process?

我试图了解Yii框架2的登录过程。当Security类使用以下代码行验证密码时,我陷入了困境。

return Yii::$app->security->validatePassword($password, $this->password_hash);

当我查看这个validatePassword()方法时,它看起来如下。

public function validatePassword($password, $hash)
{
    if (!is_string($password) || $password === '') {
        throw new InvalidParamException('Password must be a string and cannot be empty.');
    }
    if (!preg_match('/^'$2[axy]'$('d'd)'$['.'/0-9A-Za-z]{22}/', $hash, $matches) || $matches[1] < 4 || $matches[1] > 30) {
        throw new InvalidParamException('Hash is invalid.');
    }
    switch ($this->passwordHashStrategy) {
        case 'password_hash':
            if (!function_exists('password_verify')) {
                throw new InvalidConfigException('Password hash key strategy "password_hash" requires PHP >= 5.5.0, either upgrade your environment or use another strategy.');
            }
            return password_verify($password, $hash);
        case 'crypt':
            $test = crypt($password, $hash);
            $n = strlen($test);
            if ($n !== 60) {
                return false;
            }
            return $this->compareString($test, $hash);
        default:
            throw new InvalidConfigException("Unknown password hash strategy '{$this->passwordHashStrategy}'");
    }
}

当我查看compareString()方法时,它看起来如下。

public function compareString($expected, $actual)
{
    $expected .= "'0";
    $actual .= "'0";
    $expectedLength = StringHelper::byteLength($expected);
    $actualLength = StringHelper::byteLength($actual);
    $diff = $expectedLength - $actualLength;
    for ($i = 0; $i < $actualLength; $i++) {
        $diff |= (ord($actual[$i]) ^ ord($expected[$i % $expectedLength]));
    }
    return $diff === 0;
}

我不明白Yii 2是如何获得并使用salt和cost来验证和比较密码和密码哈希的?有资深开发人员知道吗?你能解释一下吗?非常感谢。

默认情况下,Yii2使用password_hash来存储和验证密码。盐和成本自动包含在password_hash算法中,我们不在乎

password_verify($password, $hash);


参考:http://php.net/manual/en/book.password.php

您可以从yii''base''Security类扩展自己的类,重新定义父方法generateSalt()、generatePasswordHash()、validatePassword(),并在yii应用程序中设置新的Security类:

 'components' => [
   ...
    'security' => [
        'class' => 'app'components'MySecurity'
    ],