我們的部落格應用程式需要區分系統擁有者和訪客使用者。因此,我們需要實作使用者驗證功能。
您可能已經發現骨架應用程式已經透過檢查使用者名稱和密碼是否皆為 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 功能以 OOP 方式存取 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 Model 中缺少 generateSalt 方法
我認為還需要在使用者方法中加入 generateSalt 方法
/** * Generates a salt that can be used to generate a password hash. * @return string the salt */ protected function generateSalt() { return uniqid('',true); }
註冊 或 登入 以發表評論。