0 关注者

验证用户

我们的博客应用程序需要区分系统所有者和访客用户。因此,我们需要实现用户验证功能。

您可能已经发现骨架应用程序已经通过检查用户名和密码是否都为demoadmin来提供用户验证。在本节中,我们将修改相应的代码,以便验证针对User数据库表进行。

用户验证是在实现IUserIdentity接口的类中执行的。骨架应用程序使用UserIdentity类来实现此目的。该类存储在文件/wwwroot/blog/protected/components/UserIdentity.php中。

提示:按照惯例,类文件的名字必须与对应的类名相同,并在后面加上扩展名.php。遵循此惯例,可以使用路径别名来引用类。例如,我们可以使用别名application.components.UserIdentity来引用UserIdentity类。Yii 中的许多 API 能够识别路径别名(例如,Yii::createComponent()),使用路径别名可以避免在代码中嵌入绝对文件路径的必要性。后者的存在在部署应用程序时经常会造成麻烦。

我们将UserIdentity类修改如下:

<?php
class UserIdentity extends CUserIdentity
{
    private $_id;
 
    public function authenticate()
    {
        $username=strtolower($this->username);
        $user=User::model()->find('LOWER(username)=?',array($username));
        if($user===null)
            $this->errorCode=self::ERROR_USERNAME_INVALID;
        else if(!$user->validatePassword($this->password))
            $this->errorCode=self::ERROR_PASSWORD_INVALID;
        else
        {
            $this->_id=$user->id;
            $this->username=$user->username;
            $this->errorCode=self::ERROR_NONE;
        }
        return $this->errorCode==self::ERROR_NONE;
    }
 
    public function getId()
    {
        return $this->_id;
    }
}

authenticate()方法中,我们使用User类在tbl_user表中查找username列与给定用户名(不区分大小写)相同的行。请记住,User类是在上一节中使用gii工具创建的。因为User类扩展自CActiveRecord,所以我们可以利用ActiveRecord 功能以面向对象的方式访问tbl_user表。

为了检查用户是否输入了有效的密码,我们调用了User类的validatePassword方法。我们需要修改文件/wwwroot/blog/protected/models/User.php,如下所示。请注意,我们不是将明文密码存储在数据库中,而是存储密码的哈希值。在验证用户输入的密码时,我们应该比较哈希结果,而不是直接比较密码。我们使用 Yii 内置的CPasswordHelper来对密码进行哈希处理并验证它。

class User extends CActiveRecord
{
    ......
    public function validatePassword($password)
    {
        return CPasswordHelper::verifyPassword($password,$this->password);
    }
 
    public function hashPassword($password)
    {
        return CPasswordHelper::hashPassword($password);
    }
}

UserIdentity类中,我们还重写了getId()方法,该方法返回在tbl_user表中找到的用户的id值。父类实现会返回用户名。usernameid属性都将存储在用户会话中,并且可以通过我们的代码中的任何位置的Yii::app()->user访问。

提示:UserIdentity类中,我们引用了类CUserIdentity,而没有显式地包含对应的类文件。这是因为CUserIdentity是 Yii 框架提供的核心类。Yii 会在首次引用核心类时自动包含该类的文件。

我们对User类也做同样的事情。这是因为User类文件被放置在/wwwroot/blog/protected/models目录下,该目录已根据以下在应用程序配置中找到的行添加到 PHP include_path

return array(
    ......
    'import'=>array(
        'application.models.*',
        'application.components.*',
    ),
    ......
);

上面的配置表示,任何类文件位于/wwwroot/blog/protected/models/wwwroot/blog/protected/components下的类,都会在首次引用该类时自动包含。

UserIdentity类主要由LoginForm类使用,它根据从登录页面收集的用户名和密码输入来验证用户。以下代码片段展示了如何使用UserIdentity

$identity=new UserIdentity($username,$password);
$identity->authenticate();
switch($identity->errorCode)
{
    case UserIdentity::ERROR_NONE:
        Yii::app()->user->login($identity);
        break;
    ......
}

信息:人们经常混淆身份和user应用程序组件。前者代表一种执行验证的方式,而后者用于表示与当前用户相关的信息。一个应用程序只能有一个user组件,但它可以有一个或多个身份类,具体取决于它支持哪种验证方式。验证成功后,身份实例可以将其状态信息传递给user组件,以便它们可以通过user全局访问。

为了测试修改后的UserIdentity类,我们可以浏览 URL http://www.example.com/blog/index.php,并尝试使用存储在tbl_user表中的用户名和密码登录。如果我们使用博客演示提供的数据库,我们应该能够使用用户名demo和密码demo登录。请注意,此博客系统不提供用户管理功能。因此,用户无法通过 Web 界面更改其帐户或创建新帐户。用户管理功能可以被视为博客应用程序的未来增强功能。

发现拼写错误或您认为此页面需要改进?
在 github 上编辑它 !