我們的blog應用要區分系統使用者和訪客的不同身份。是以需要實作使用者的驗證部分。
或許你已經看到系統提供了一個使用者驗證,通過檢查admin和demo的使用者名密碼。在這節中我們修改這段代碼,讓使用者驗證根據User表裡的資料進行驗證。
使用者驗證是由實作了IUserIdentity接口的的一個類來實作的。我們的應用架構中使用類UserIdentity來實作此目标.該檔案存放在/wwwroot/blog/protected/components/UserIdentity.php。
約定class檔案的名字必須和class的名字元合。也即是說類的名字加上".php"就是存放改類的檔案的名字。按照這樣的約定。我們可以引用一個class通過路徑的别名。如:我們可以通過這樣的别名application.components.UserIdentity使用UserIdentity類。多數的Yii APIs可以識别這樣的别名(如 Yii::createComponent()),通過使用這樣的别名來避免嵌入絕對的位址。後者往往在我們部署一個應用的時候帶來麻煩。
我們如下修改使用者驗證的檔案。
- <?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(md5($this->password)!==$user->password)
- $this->errorCode=self::ERROR_PASSWORD_INVALID;
- else
- {
- $this->_id=$user->id;
- $this->username=$user->username;
- $this->errorCode=self::ERROR_NONE;
- }
- return !$this->errorCode;
- }
- public function getId()
- return $this->_id;
- }
在 authenticate()方法中,我們User類來檢查在資料表中是否存在該使用者名,檢查時通過轉換為小寫來不區分大小寫。User類是在上一節中通過Yiic工具來實作的。因為User類是繼承CActiveRecord。我們可以用oop的風格來擴充CActiveRecord和對User表的資料進行存取
在UserIdentity類中我們重寫了getId()方法,用于傳回在資料表中查找到得使用者id,在其父類中傳回的是使用者名。使用者名和id屬性被儲存到user session中,在程式的任何地方可以通過Yii::app()->user進行存取通路。
在使用者驗證的類中我們使用其他的類文沒有明顯的去加載他們,這是因為這些類是Yii framework提過的核心類,當他們第一次沒使用的時候,Yii自動的加載他們。User類也可以這麼直接使用,這是因為他存放在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;
- ......
人們經常會混淆了identity和user兩個元件。前者實作了使用者的驗證,後者提供了目前使用者的相關資訊。一個應用隻能有一個user元件,但是可以有一個或者多個驗證類,取決于它支援的驗證類型。一旦驗證成功,一個identity 執行個體會把它的狀态資訊傳遞給user組(Once authenticated, an identity instance may pass its state information to the user component so that they are globally accessible via user)