Yii2框架实现登录、退出及自动登录功能的方法详解
本文实例讲述了Yii2框架实现登录、退出及自动登录功能的方法。分享给大家供大家参考,具体如下:
自动登录的原理很简单。主要就是利用cookie来实现的
在第一次登录的时候,如果登录成功并且选中了下次自动登录,那么就会把用户的认证信息保存到cookie中,cookie的有效期为1年或者几个月。
在下次登录的时候先判断cookie中是否存储了用户的信息,如果有则用cookie中存储的用户信息来登录,
配置User组件
首先在配置文件的components中设置user组件
'user'=>[ 'identityClass'=>'app\models\User', 'enableAutoLogin'=>true, ],
我们看到enableAutoLogin就是用来判断是否要启用自动登录功能,这个和界面上的下次自动登录无关。
只有在enableAutoLogin为true的情况下,如果选择了下次自动登录,那么就会把用户信息存储起来放到cookie中并设置cookie的有效期为3600*24*30秒,以用于下次登录
现在我们来看看Yii中是怎样实现的。
一、第一次登录存cookie
1、login登录功能
publicfunctionlogin($identity,$duration=0) { if($this->beforeLogin($identity,false,$duration)){ $this->switchIdentity($identity,$duration); $id=$identity->getId(); $ip=Yii::$app->getRequest()->getUserIP(); Yii::info("User'$id'loggedinfrom$ipwithduration$duration.",__METHOD__); $this->afterLogin($identity,false,$duration); } return!$this->getIsGuest(); }
在这里,就是简单的登录,然后执行switchIdentity方法,设置认证信息。
2、switchIdentity设置认证信息
publicfunctionswitchIdentity($identity,$duration=0) { $session=Yii::$app->getSession(); if(!YII_ENV_TEST){ $session->regenerateID(true); } $this->setIdentity($identity); $session->remove($this->idParam); $session->remove($this->authTimeoutParam); if($identityinstanceofIdentityInterface){ $session->set($this->idParam,$identity->getId()); if($this->authTimeout!==null){ $session->set($this->authTimeoutParam,time()+$this->authTimeout); } if($duration>0&&$this->enableAutoLogin){ $this->sendIdentityCookie($identity,$duration); } }elseif($this->enableAutoLogin){ Yii::$app->getResponse()->getCookies()->remove(newCookie($this->identityCookie)); } }
这个方法比较重要,在退出的时候也需要调用这个方法。
这个方法主要有三个功能
①设置session的有效期
②如果cookie的有效期大于0并且允许自动登录,那么就把用户的认证信息保存到cookie中
③如果允许自动登录,删除cookie信息。这个是用于退出的时候调用的。退出的时候传递进来的$identity为null
protectedfunctionsendIdentityCookie($identity,$duration) { $cookie=newCookie($this->identityCookie); $cookie->value=json_encode([ $identity->getId(), $identity->getAuthKey(), $duration, ]); $cookie->expire=time()+$duration; Yii::$app->getResponse()->getCookies()->add($cookie); }
存储在cookie中的用户信息包含有三个值:
$identity->getId()
$identity->getAuthKey()
$duration
getId()和getAuthKey()是在IdentityInterface接口中的。我们也知道在设置User组件的时候,这个UserModel是必须要实现IdentityInterface接口的。所以,可以在UserModel中得到前两个值,第三值就是cookie的有效期。
二、自动从cookie登录
从上面我们知道用户的认证信息已经存储到cookie中了,那么下次的时候直接从cookie里面取信息然后设置就可以了。
1、AccessControl用户访问控制
Yii提供了AccessControl来判断用户是否登录,有了这个就不需要在每一个action里面再判断了
publicfunctionbehaviors() { return[ 'access'=>[ 'class'=>AccessControl::className(), 'only'=>['logout'], 'rules'=>[ [ 'actions'=>['logout'], 'allow'=>true, 'roles'=>['@'], ], ], ], ]; }
2、getIsGuest、getIdentity判断是否认证用户
isGuest是自动登录过程中最重要的属性。
在上面的AccessControl访问控制里面通过IsGuest属性来判断是否是认证用户,然后在getIsGuest方法里面是调用getIdentity来获取用户信息,如果不为空就说明是认证用户,否则就是游客(未登录)。
publicfunctiongetIsGuest($checkSession=true) { return$this->getIdentity($checkSession)===null; } publicfunctiongetIdentity($checkSession=true) { if($this->_identity===false){ if($checkSession){ $this->renewAuthStatus(); }else{ returnnull; } } return$this->_identity; }
3、renewAuthStatus重新生成用户认证信息
protectedfunctionrenewAuthStatus() { $session=Yii::$app->getSession(); $id=$session->getHasSessionId()||$session->getIsActive()?$session->get($this->idParam):null; if($id===null){ $identity=null; }else{ /**@varIdentityInterface$class*/ $class=$this->identityClass; $identity=$class::findIdentity($id); } $this->setIdentity($identity); if($this->authTimeout!==null&&$identity!==null){ $expire=$session->get($this->authTimeoutParam); if($expire!==null&&$expire
这一部分先通过session来判断用户,因为用户登录后就已经存在于session中了。然后再判断如果是自动登录,那么就通过cookie信息来登录。
4、通过保存的Cookie信息来登录loginByCookie
protectedfunctionloginByCookie() { $name=$this->identityCookie['name']; $value=Yii::$app->getRequest()->getCookies()->getValue($name); if($value!==null){ $data=json_decode($value,true); if(count($data)===3&&isset($data[0],$data[1],$data[2])){ list($id,$authKey,$duration)=$data; /**@varIdentityInterface$class*/ $class=$this->identityClass; $identity=$class::findIdentity($id); if($identity!==null&&$identity->validateAuthKey($authKey)){ if($this->beforeLogin($identity,true,$duration)){ $this->switchIdentity($identity,$this->autoRenewCookie?$duration:0); $ip=Yii::$app->getRequest()->getUserIP(); Yii::info("User'$id'loggedinfrom$ipviacookie.",__METHOD__); $this->afterLogin($identity,true,$duration); } }elseif($identity!==null){ Yii::warning("Invalidauthkeyattemptedforuser'$id':$authKey",__METHOD__); } } } }
先读取cookie值,然后$data=json_decode($value,true);反序列化为数组。
这个从上面的代码可以知道要想实现自动登录,这三个值都必须有值。另外,在UserModel中还必须要实现findIdentity、validateAuthKey这两个方法。
登录完成后,还可以再重新设置cookie的有效期,这样便能一起有效下去了。
$this->switchIdentity($identity,$this->autoRenewCookie?$duration:0);
三、退出logout
publicfunctionlogout($destroySession=true) { $identity=$this->getIdentity(); if($identity!==null&&$this->beforeLogout($identity)){ $this->switchIdentity(null); $id=$identity->getId(); $ip=Yii::$app->getRequest()->getUserIP(); Yii::info("User'$id'loggedoutfrom$ip.",__METHOD__); if($destroySession){ Yii::$app->getSession()->destroy(); } $this->afterLogout($identity); } return$this->getIsGuest(); } publicfunctionswitchIdentity($identity,$duration=0) { $session=Yii::$app->getSession(); if(!YII_ENV_TEST){ $session->regenerateID(true); } $this->setIdentity($identity); $session->remove($this->idParam); $session->remove($this->authTimeoutParam); if($identityinstanceofIdentityInterface){ $session->set($this->idParam,$identity->getId()); if($this->authTimeout!==null){ $session->set($this->authTimeoutParam,time()+$this->authTimeout); } if($duration>0&&$this->enableAutoLogin){ $this->sendIdentityCookie($identity,$duration); } }elseif($this->enableAutoLogin){ Yii::$app->getResponse()->getCookies()->remove(newCookie($this->identityCookie)); } }
退出的时候先把当前的认证设置为null,然后再判断如果是自动登录功能则再删除相关的cookie信息。
更多关于Yii相关内容感兴趣的读者可查看本站专题:《Yii框架入门及常用技巧总结》、《php优秀开发框架总结》、《smarty模板入门基础教程》、《php面向对象程序设计入门教程》、《php字符串(string)用法总结》、《php+mysql数据库操作入门教程》及《php常见数据库操作技巧汇总》
希望本文所述对大家基于Yii框架的PHP程序设计有所帮助。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。