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 功能以 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 值。父類別實作會改為傳回使用者名稱。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 上編輯 !