一直在使用yii进行开发, 也知道如何去使用, 也仅仅是知道怎么去用罢了, 终归是没研究过源码, 心里发虚, 今天遇到一个问题, 关于自动登陆的问题.
要求就是, 修改登陆保存session天数为自定义1, 2, 3 ... 等天数, 然后, 把原有的session信息清理掉.
前面一段好操作, 就是在登陆时, 把记住一个月, 修改为多个值, 然后, 传值给 login 方法即可, 后一个把原登陆session信息给清理掉, 这个就不知如何操作了
原来想的是服务器上存储的有session信息, 我把session全删了, 一切搞定, 但事实并非这样, 因为打印出来的session信息, 只有设置过的redis的记录, 其他的没有.
然后就看源码, 以上口水可以忽略, 以下是个人心得:
在 framework/web/auth/CWebUser.php 里有如下代码
>---public function init() >---{ >--->---parent::init(); >--->---Yii::app()->getSession()->open(); >--->---if($this->getIsGuest() && $this->allowAutoLogin) >--->--->---$this->restoreFromCookie(); >--->---elseif($this->autoRenewCookie && $this->allowAutoLogin) >--->--->---$this->renewCookie(); >--->---if($this->autoUpdateFlash) >--->--->---$this->updateFlash(); >--->---$this->updateAuthStatus(); >---}
>---protected function restoreFromCookie() >---{ >--->---$app=Yii::app(); >--->---$request=$app->getRequest(); >--->---$cookie=$request->getCookies()->itemAt($this->getStateKeyPrefix()); >--->---if($cookie && !empty($cookie->value) && is_string($cookie->value) && ($data=$app->getSecurityManager()->validateData($cookie->value))!==false) >--->---{ >--->--->---$data=@unserialize($data); >--->--->---if(is_array($data) && isset($data[0],$data[1],$data[2],$data[3])) >--->--->---{ >--->--->--->---list($id,$name,$duration,$states)=$data; >--->--->--->---if($this->beforeLogin($id,$states,true)) >--->--->--->---{ >--->--->--->--->---$this->changeIdentity($id,$name,$states); >--->--->--->--->---if($this->autoRenewCookie) >--->--->--->--->---{ >--->--->--->--->--->---$this->saveToCookie($duration); >--->--->--->--->---} >--->--->--->--->---$this->afterLogin(true); >--->--->--->---} >--->--->---} >--->---} >---}
用vim打开源码有自带的空白转变成了 >-->这样的, 不想管它了, 找着代码在哪就行 - -!
然后, 我把下面的一段摘录出来, 看一下.
$app=Yii::app(); $request=$app->getRequest(); $cookie=$request->getCookies(); $cookie = $cookie['admin']; echo 'admin的cookie值' . '<br />'; var_dump($cookie); if($cookie && !empty($cookie->value) && is_string($cookie->value) && ($data=$app->getSecurityManager()->validateData($cookie->value))!==false) { echo '验证以后, 未进行序列化前的值' . '<br />'; var_dump($data); $data=@unserialize($data); echo '序列化以后的值' . '<br />'; var_dump($data); if(is_array($data) && isset($data[0],$data[1],$data[2],$data[3])) { list($id,$name,$duration,$states)=$data; echo 'cookie所加时间(秒计)' . '<br />'; var_dump($duration);die; } }
输出如下
admin的cookie值
object(CHttpCookie)[548]
public 'name' =>
string
'admin' (length=5) public 'value' =>
string
'dvdsdsefeveererererefdsafdsvcdsavsaa:4:{i:0;s:1:"1";i:1;s:5:"admin";i:2;i:2592000;i:3;a:2:{s:4:"role";s:3:"100";s:3:"uid";s:1:"1";}}' (length=137) public 'domain' =>
string
'' (length=0) public 'expire' =>
int
0 public 'path' =>
string
'/' (length=1) public 'secure' =>
boolean
false public 'httpOnly' =>
boolean
false
private '_e'
(CComponent)
=> null private '_m'
(CComponent)
=> null
验证以后, 未进行序列化前的值
string
'a:4:{i:0;s:1:"1";i:1;s:5:"admin";i:2;i:2592000;i:3;a:2:{s:4:"role";s:3:"100";s:3:"uid";s:1:"1";}}' (length=97)
序列化以后的值
array (size=4)
0 =>
string
'1' (length=1) 1 =>
string
'admin' (length=5) 2 =>
int
2592000 3 => array (size=2) 'role' =>
string
'100' (length=3) 'uid' =>
string
'1' (length=1)
cookie所加时间(秒计)
int
2592000
它是使用自有方法去验证, 得到的cookie是不是自己生成的( $app->getSecurityManager()->validateData($cookie->value) )
如果是, 把内容反序列化, 取出日期, 自动登陆, 同时, 把有效期重新往后沿续, 不是的话, 不处理, 也就是说, 需要重新登陆
时间仓促, 写的不好, 只是作个简单记录, 下面这篇文章写的是登陆流程, 可作参考, 这篇文章是对yii如何实现自动登陆的一个手写草稿, 待有时间再完善
http://www.cnblogs.com/jmax/archive/2010/07/21/1782396.html yii 登陆流程参考