yii自动登陆的验证机制浅析

一直在使用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 登陆流程参考

 

 

 

 

posted @ 2014-09-16 15:52  Debm.Zhang  阅读(655)  评论(0编辑  收藏  举报