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

Yii 1.x 前後台登錄分離:雙 CWebUser 實例實現互不干擾

     編輯:PHP 相關知識

痛點

單一 CWebUser 實例導致前後台共用 Session,登錄/退出相互影響。解決思路:為後台模塊註冊獨立的 CWebUser 子類實例(如 AdminWebUser),並設置不同的 stateKeyPrefix。

1. 主配置:前台 user 組件

'components'=>[
    'user'=>[
        'class'=>'WebUser',          // 繼承 CWebUser
        'stateKeyPrefix'=>'member',  // 前台 session 前綴
        'allowAutoLogin'=>true,
    ],
],

2. 後台模塊 AdminModule.php:註冊獨立 admin 組件

class AdminModule extends CWebModule {
    public function init() {
        parent::init();
        $this->setImport(['admin.models.*', 'admin.components.*']);

        Yii::app()->setComponents([
            'errorHandler'=>['class'=>'CErrorHandler', 'errorAction'=>'admin/default/error'],
            'admin'=>[                // 後台專用 user 組件
                'class'=>'AdminWebUser',
                'stateKeyPrefix'=>'admin', // 後台 session 前綴
                'loginUrl'=>Yii::app()->createUrl('admin/default/login'),
            ],
        ], false); // false = 不覆蓋已有組件
    }

    public function beforeControllerAction($controller, $action) {
        if (parent::beforeControllerAction($controller, $action)) {
            $route = $controller->id.'/'.$action->id;
            $public = ['default/login', 'default/error'];
            if (Yii::app()->admin->isGuest && !in_array($route, $public))
                Yii::app()->admin->loginRequired();
            return true;
        }
        return false;
    }
}

3. 兩套 WebUser 實現(存儲用戶信息到各自 state)

// 前台 WebUser
class WebUser extends CWebUser {
    public function __get($name) {
        if ($this->hasState('__userInfo')) {
            $u = $this->getState('__userInfo', []);
            if (isset($u[$name])) return $u[$name];
        }
        return parent::__get($name);
    }
    public function login($identity, $duration) {
        $this->setState('__userInfo', $identity->getUser());
        parent::login($identity, $duration);
    }
}

// 後台 AdminWebUser(結構同前台,鍵名改為 __adminInfo)
class AdminWebUser extends CWebUser {
    public function __get($name) {
        if ($this->hasState('__adminInfo')) {
            $u = $this->getState('__adminInfo', []);
            if (isset($u[$name])) return $u[$name];
        }
        return parent::__get($name);
    }
    public function login($identity, $duration) {
        $this->setState('__adminInfo', $identity->getUser());
        parent::login($identity, $duration);
    }
}

4. 退出登錄:只銷毀當前前綴的 Session

// 前台退出
Yii::app()->user->logout(false); // false = 不銷毀整個 session

// 後台退出
Yii::app()->admin->logout(false);

CWebUser::logout(false) 內部調用 clearStates(),僅刪除 $_SESSION 中以當前 stateKeyPrefix 開頭的鍵,實現精準隔離。

5. 身份驗證類(UserIdentity)分離

前台驗證 User 表,後台驗證 Staff 表,各自實現 authenticate()、getUser()、getId(),登錄時傳入對應 CWebUser 實例即可。

使用入口

  • 前台:Yii::app()->user
  • 後台:Yii::app()->admin

此方案在單入口、單應用下實現了真正的前後台會話隔離,避免雙入口維護成本。

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