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();
    }
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值