我们的博客应用程序需要区分系统所有者和访客用户。因此,我们需要实现用户验证功能。
您可能已经发现骨架应用程序已经通过检查用户名和密码是否都为demo
或admin
来提供用户验证。在本节中,我们将修改相应的代码,以便验证针对User
数据库表进行。
用户验证是在实现IUserIdentity接口的类中执行的。骨架应用程序使用UserIdentity
类来实现此目的。该类存储在文件/wwwroot/blog/protected/components/UserIdentity.php
中。
提示:按照惯例,类文件的名字必须与对应的类名相同,并在后面加上扩展名
.php
。遵循此惯例,可以使用路径别名来引用类。例如,我们可以使用别名application.components.UserIdentity
来引用UserIdentity
类。Yii 中的许多 API 能够识别路径别名(例如,Yii::createComponent()),使用路径别名可以避免在代码中嵌入绝对文件路径的必要性。后者的存在在部署应用程序时经常会造成麻烦。
我们将UserIdentity
类修改如下:
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
值。父类实现会返回用户名。username
和id
属性都将存储在用户会话中,并且可以通过我们的代码中的任何位置的Yii::app()->user
访问。
提示:在
UserIdentity
类中,我们引用了类CUserIdentity,而没有显式地包含对应的类文件。这是因为CUserIdentity是 Yii 框架提供的核心类。Yii 会在首次引用核心类时自动包含该类的文件。我们对
User
类也做同样的事情。这是因为User
类文件被放置在/wwwroot/blog/protected/models
目录下,该目录已根据以下在应用程序配置中找到的行添加到 PHPinclude_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 上编辑它 !
User 模型中缺少 generateSalt 方法
我认为还需要在 user 方法中添加 generateSalt 方法
/** * Generates a salt that can be used to generate a password hash. * @return string the salt */ protected function generateSalt() { return uniqid('',true); }
注册 或 登录 以评论。