Yii2 登录验证

后端都知道,数据库中最好是存储密码的哈希值而不是明文密码,以防止潜在的攻击所带来的损失。而随着现今设备计算能力的提升,一些哈希算法变得越来越不安全(以前常用的 MD5 已经被证实可被部分破解,推荐使用 SHA1 及更高安全等级的算法)。

Yii2 框架提供了一个方便使用的安全类 \yii\base\Security,其中的方法可以方便快速的进行随机数生成、hash计算、hash验证等实用操作。用来做登录验证也正好合适。

\yii\base\Security 中的 generatePasswordHash() 方法可以生成一串60位字符长度的hash值,而且每次生成的结果都不一样(因为其依赖的 salt 值是随机生成的),安全性很高。看源码可知其加密依赖的是 PHP 内置的 crypt()
函数:

public function generatePasswordHash($password, $cost = null)
{
    if ($cost === null) {
        $cost = $this->passwordHashCost;
    }

    if (function_exists('password_hash')) {
        /* @noinspection PhpUndefinedConstantInspection */
        return password_hash($password, PASSWORD_DEFAULT, ['cost' => $cost]);
    }

    $salt = $this->generateSalt($cost);
    $hash = crypt($password, $salt);
    // strlen() is safe since crypt() returns only ascii
    if (!is_string($hash) || strlen($hash) !== 60) {
            throw new Exception('Unknown error occurred while generating hash.');
    }

    return $hash;
}

既然每次生成的结果都不一致,那么每次登录的时候如何验证?别担心!\yii\base\Security 还提供了一个 validatePassword() 方法,用来验证字符串和哈希值是否匹配,其中第一个变量是密码明文,第二个变量是 generatePasswordHash() 生成的哈希值:

public function validatePassword($password, $hash)
{
    // ...
}

实践中大概是这样的用法

生成哈希值,用来存数据库

$password = '123456';
$password_hash = Yii::$app->security->generatePasswordHash($password);
// save $password_hash to DB

如果要把哈希值存到数据库,一定记得字段类型需要是 char、varchar、vartext 或 text 类型,长度要足够存储60位字符。

登录验证

$password = '123456'; // get user input
$password_hash = '$2y$13$FuhCQhAmoW9/95d0IYo5EeynoQggfMJy3oBoUTMSlDo2VGBLzJc5m'; // get from DB
if (Yii::$app->security->validatePassword($password, $password_hash)){
    // successful ! do somethig.
} else {
    // unsuccessful !
}

并不是一定要使用 Yii 框架提供的安全类来生成哈希,也可以直接用 PHP 内置的 sha1()sha256()crypt() 等函数,视情况定。

猜你喜欢

转载自www.cnblogs.com/alanabc/p/9393729.html