首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

Yii 框架登錄機制深度解析:從自動生成到數據庫驅動與自動登錄實現

     編輯:PHP 綜合知識

Yiiframework 內建完整的用戶認證體系。本文層層剖析:自動生成代碼結構 → 核心類職責 → 數據庫驅動改造 → 自動登錄(Remember Me)原理與實現。

一、自動生成的登錄架構(MVC 分層)

層級文件/類核心職責
ComponentUserIdentity最基礎的身份驗證邏輯(預設硬編碼 demo/admin)
ModelLoginForm (extends CFormModel)封裝表單數據、驗證規則、調用 UserIdentity、執行登錄
ControllerSiteController::actionLogin()接收 POST、實例化 LoginForm、驗證並登錄或渲染視圖
Viewviews/site/login.php登錄頁面模板

核心代碼流向

// LoginForm::authenticate() → UserIdentity::authenticate()
public function authenticate($attribute,$params) {
    $this->_identity = new UserIdentity($this->username, $this->password);
    if (!$this->_identity->authenticate())
        $this->addError('password', '用戶名或密碼錯誤');
}

// LoginForm::login() → Yii::app()->user->login()
public function login() {
    if ($this->_identity === null) { /* 實例化並驗證 */ }
    if ($this->_identity->errorCode === UserIdentity::ERROR_NONE) {
        $duration = $this->rememberMe ? 3600*24*30 : 0; // 30天 或 會話級
        Yii::app()->user->login($this->_identity, $duration);
        return true;
    }
    return false;
}

二、改造 UserIdentity 接入數據庫

假設已建表 admin(字段:admin_id, username, psw[雙重 SHA1], nick, login_time)。

// components/UserIdentity.php
public function authenticate() {
    // 1. 密碼雙重 SHA1(與存儲一致)
    if (strlen($this->password) > 0)
        $this->password = sha1(sha1($this->password));

    // 2. 查找用戶
    $user = Admin::model()->findByAttributes(['username' => $this->username]);

    // 3. 驗證邏輯
    if ($user === null)
        $this->errorCode = self::ERROR_USERNAME_INVALID;
    elseif (!($user instanceof Admin) || $user->psw !== $this->password)
        $this->errorCode = self::ERROR_PASSWORD_INVALID;
    else {
        // 4. 設置狀態:登錄後可直接用 Yii::app()->user->nick 訪問
        $this->setState('admin_id', $user->admin_id);
        $this->setState('nick', $user->nick);
        $this->setState('username', $user->username);

        // 5. 更新最後登錄時間
        $user->login_time = date('Y-m-d H:i:s');
        $user->save();

        $this->errorCode = self::ERROR_NONE;
    }
    return !$this->errorCode;
}

三、自動登錄(Remember Me)完整機制

1. 配置啟用

// config/main.php
'components' => [
    'user' => [
        'class' => 'WebUser', // 或 CWebUser
        'allowAutoLogin' => true, // 關鍵開關
        'identityClass' => 'app\models\User', // Yii2 風格
    ],
],

2. 登錄時寫入 Cookie(WebUser::login → switchIdentity → sendIdentityCookie)

protected function sendIdentityCookie($identity, $duration) {
    $cookie = new Cookie($this->identityCookie);
    $cookie->value = json_encode([
        $identity->getId(),       // 用戶 ID
        $identity->getAuthKey(),  // 驗證密鑰(防偽造)
        $duration,                // 有效期
    ]);
    $cookie->expire = time() + $duration;
    Yii::$app->getResponse()->getCookies()->add($cookie);
}

Cookie 內容:[user_id, auth_key, duration],經 JSON 編碼存儲。

3. 後續訪問自動識別(renewAuthStatus → loginByCookie)

  1. 優先檢查 Session 是否有效(getIdentity())。
  2. Session 失效且啟用自動登錄 → 讀取 Cookie → loginByCookie()。
  3. 解析 Cookie,調用 User::findIdentity($id) 獲取用戶對象。
  4. 驗證 validateAuthKey($authKey) 防篡改。
  5. 通過則 switchIdentity() 重建登錄態,並可選續期 Cookie(autoRenewCookie)。

4. 退出登錄清理

public function logout($destroySession = true) {
    $identity = $this->getIdentity();
    if ($identity !== null) {
        $this->switchIdentity(null); // 關鍵:傳 null 觸發 Cookie 刪除
        if ($destroySession) Yii::$app->getSession()->destroy();
    }
    return $this->getIsGuest();
}

四、關鍵接口:IdentityInterface

自定義用戶模型必須實現:

  • findIdentity($id):根據 ID 找用戶
  • findIdentityByAccessToken($token):API 認證用
  • getId()、getAuthKey()、validateAuthKey($authKey)

總結

Yii 登錄體系設計精妙:UserIdentity 負責驗證邏輯,LoginForm 封裝表單交互,WebUser 管理會話狀態與 Cookie 持久化。遷移到數據庫只需重寫 UserIdentity::authenticate();自動登錄則靠 allowAutoLogin + Cookie(JSON) + IdentityInterface 三位一體實現。理解這套機制,靈活定製認證流程將得心應手。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved