Yii 用戶登錄和註銷流程

屬個人理解,有出錯的地方請評論指出,謝謝~
用戶登錄時,調用默認控制器siteController/actionLogin
public function actionLogin()
    {
        $model=new LoginForm;

        // if it is ajax validation request
        if(isset($_POST['ajax']) && $_POST['ajax']==='login-form')
        {
            echo CActiveForm::validate($model);
            Yii::app()->end();
        }

        // collect user input data
        if(isset($_POST['LoginForm']))
        {
            $model->attributes=$_POST['LoginForm'];
            // validate user input and redirect to the previous page if valid
            if($model->validate() && $model->login())
                $this->redirect(Yii::app()->user->returnUrl);
        }
        // display the login form
        $this->render('login',array('model'=>$model));
    }
用戶提交表單後,實例化LoginForm模型,再實例化組件UserIdentity,調用UserIdentity/authenticate
public function authenticate()
    {
        $users=MngUserMain::model()->findByAttributes(array('username'=>$this->username));
        if($users==NULL)
            $this->errorCode=self::ERROR_USERNAME_INVALID;
        else if($users->password!==$this->password)
            $this->errorCode=self::ERROR_PASSWORD_INVALID;
        else{
            $this->_id=$users->id;
            $this->setState('department_id', $users->student_num);
            $department = MngDepartment::model()->findByPk($users->student_num);
            $this->setState('department_name', $department->name);
            $this->errorCode=self::ERROR_NONE;
        }
            
        return !$this->errorCode;
    }
通過數據庫匹配用戶輸入,如果帳號密碼正確,則讓用戶登錄,LoginForm/login執行了這個操作
public function login()
    {
        if($this->_identity===null)
        {
            $this->_identity=new UserIdentity($this->username,$this->password);
            $this->_identity->authenticate();
        }
        if($this->_identity->errorCode===UserIdentity::ERROR_NONE)
        {
            $duration=$this->rememberMe ? 3600*24*30 : 0; // 30 days
            Yii::app()->user->login($this->_identity,$duration);
            return true;
        }
        else
            return false;
    }
此處調用了Yii::app()->user->login($this->_identity,$duration)這個函數爲CWebUser/login,用於生成session和爲CWebUser實例的一些變量賦值
public function login($identity,$duration=0)
{
    $id=$identity->getId();//這裏是記錄的id
    $states=$identity->getPersistentStates();//這裏是setState函數設置的一些額外的屬性,是array
    if($this->beforeLogin($id,$states,false))
    {
        $this->changeIdentity($id,$identity->getName(),$states);//$identity->getName()爲返回CUserIdentity實例中的username的值

        if($duration>0)
        {
            if($this->allowAutoLogin)
                $this->saveToCookie($duration);
            else
                throw new CException(Yii::t('yii','{class}.allowAutoLogin must be set true in order to use cookie-based authentication.',
                    array('{class}'=>get_class($this))));
        }

        $this->afterLogin(false);
    }
    return !$this->getIsGuest();
}
在changeIdentity中,設置了$_SESSION[$key]這個seesion,其實設置的是$_SESSION['前綴__id']=$id(記錄的id),$_SESSION['前綴__name']=$username(記錄的username),並且把我們自定義額外添加的一些屬性也設置了$_SESSION['前綴+屬性名']=$屬性值(這裏所指的額外屬性是在UserIdentity組件中我們調用setState()函數設置的,以後可以通過Yii::app()->user->屬性取值),如果$duration大於0(記住用戶登錄狀態時間,默認是0),則設置cookie,allowAutoLogin是在main.php中設置的值(默認爲true)。
protected function saveToCookie($duration)
{
    
$app=Yii::app();//實例化CApplication
    
$cookie=$this->createIdentityCookie($this->getStateKeyPrefix());
    
$cookie->expire=time()+$duration;//cookie有效時間
    
$data=array(
        
$this->getId(),//用戶的唯一標識符。如果是空,意味着用戶是來賓用戶。,返回的是$_SESSION[‘id’],
        
$this->getName(),//返回的是$_SESSION['username']
        
$duration,
        
$this->saveIdentityStates(),//返回一個名爲$states數組,存儲了我們自定義的額外屬性
    );
    
$cookie->value=$app->getSecurityManager()->hashData(serialize($data));//先返回CSecurityManager實例,再調用哈希函數hashData,返回的是加密過的數據
    
$app->getRequest()->getCookies()->add($cookie->name,$cookie);//添加cookie,cookie的name一般爲$this->getStateKeyPrefix()
}

$_SESSION[$key]中的$key=$this->getStateKeyPrefix().$key,其中getStateKeyPrefix()返回的是md5('Yii.'.get_class($this).'.'.Yii::app()->getId())
此後,當訪問每一個控制器時,將通過調用Yii::app()->user->isGuest判斷用戶是否登錄。
用戶註銷時調用CWebUser/logout銷燬session,對於cookie,要看用戶是否設置了記住登錄,對於註銷時cookie的消除並不太懂!以後再分析。
下面是logout動作,有些地方不清楚,請知道的人指點下~
public function logout($destroySession=true)
{
    if(
$this->beforeLogout())
    {
        if(
$this->allowAutoLogin)
        {
            
Yii::app()->getRequest()->getCookies()->remove($this->getStateKeyPrefix());//銷燬$_COOKIE['$this->getStateKeyPrefix()']
            if(
$this->identityCookie!==null)//identityCookie這個屬性找不到在哪有賦值過!這裏不清楚!我以爲是用戶選擇了記住登錄狀態後,在用戶註銷時保存一些下次能直接登錄用的cookie,
            {
                
$cookie=$this->createIdentityCookie($this->getStateKeyPrefix());
                
$cookie->value=null;
                
$cookie->expire=0;//但這裏,當設置cookie過期時間爲0或者忽略不設置的情況下,cookie將會在session過期後過期(即瀏覽器關閉後cookie過期)
                
Yii::app()->getRequest()->getCookies()->add($cookie->name,$cookie);
            }
        }
        if(
$destroySession)
            
Yii::app()->getSession()->destroy();
        else
            
$this->clearStates();
        
$this->afterLogout();
    }
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章