最近使用Yii框架给公司开发了两个小型项目,积累了一些知识,在此进行汇总一下,以便将来项目用到时,可以参考。


  1. 关于用户登录注销功能。

    1. CWebUser class,使用这个组件能轻松实现用户登录,需要个性化设置session变量时,可以创建一个类继承CWebUser 且重写 login()方法,比如:


      public function login($identity, $duration=0) 

        {     

              $this->setState('__userInfo', array('__id'=>$identity->getId(),'__name'=>$identity->getName(),'__firstName'=>$identity->getFirstName()));

              

              parent::login($identity, $duration);  

             

        }

    2. 注销时,如果不希望将该应用的所有session都删除,可以这样写Yii::app()->user->logout(false);

 登录时,需要验证用户身份,Yii中使用UserIdentity类来处理该逻辑。参考代码如下:

  

public function Authenticate()

    {

        $member = TMember::model()->findByAttributes(array('EMAIL'=>$this->username,'PASSWORD'=>md5($this->password),'IS_ACTIVED'=>1));

                

                if($member)

                {                                          

                        $this->setId($member->ID);

                        $this->setName($member->EMAIL);      

                        $this->setFirstName($member->FIRST_NAME);

                        $this->setPassword($this->password);

                        $this->errorCode=self::ERROR_NONE;

                    

                }else{

                    $rs1 = TMember::model()->findByAttributes(array('EMAIL'=>$this->username));

                    $rs2 = TMember::model()->findByAttributes(array('PASSWORD'=>$this->password));

                    $rs3 = TMember::model()->findByAttributes(array('EMAIL'=>$this->username,'PASSWORD'=>md5($this->password)));

                     if(!$rs3){

                    if(!$rs1){

                        $this->errorCode=self::ERROR_USERNAME_INVALID;

                    }else{

                        if(!$rs2){

                          $this->errorCode=self::ERROR_PASSWORD_INVALID;  

                        }

                      }                        

                    }else{

                        $this->errorCode=self::ERROR_IS_NOT_ACTIVED;

                    }

                }

                

                 $this->tErrorCode['front'] = $this->errorCode;

                return !$this->tErrorCode['front'];

    }


2.  采用cookie以及session实现跨域登录

   首先,要搭建好环境,比如设置虚拟域名。


   a. 首先修改C:\Windows\System32\drivers\etc目录下的 hosts 文件,用记事本打开,加入:

      127.0.0.1 mc.meztalks.com 127.0.0.1 meztalks.com记得去掉前面的#


     127.0.0.1 mc.meztalks.com

     127.0.0.1 meztalks.com

     127.0.0.1 test.meztalks.com

步骤阅读

Yii项目开发总结_identity

 







b.打开xampp\apache\conf\httpd.conf文件,搜索 “Include conf/extra/httpd-vhosts.conf”,确保前面没有 # 注释符,也就是确保引入了 vhosts 虚拟主机配置文件。效果如下:

# Virtual hosts

Include "conf/extra/httpd-vhosts.conf"

开启了httpd-vhosts.conf,默认a的httpd.conf默认配置失效(确保 httpd-vhosts.conf 文件里也开启了虚拟主机配置,见第3条),访问此IP的域名将全部指向 vhosts.conf 中的第一个虚拟主机。


c. 定位apache安装目录,如:D:\wamp\bin\apache\apache2.4.9\conf\extra,编辑httpd-vhosts.conf, 设置想要配置的项目目录,

<VirtualHost *:80>

    ServerAdmin webmaster@dummy-host2.example.com

    DocumentRoot "E:/eztalks/eztalks-com/"

    ServerName meztalks.com

#ErrorLog "logs/dummy-host2.example.com-error.log"

#CustomLog "logs/dummy-host2.example.com-access.log" common

</VirtualHost>


<VirtualHost *:80>

    ServerAdmin webmaster@dummy-host2.example.com

    DocumentRoot "E:/eztalks/meetingcenter/"

    ServerName mc.meztalks.com

    ServerAlias mc.meztalks.com

DirectoryIndex index.php index.html index.htm

   #ErrorLog "logs/dummy-host.example.com-error.log"

   #CustomLog "logs/dummy-host.example.com-access.log" common

</VirtualHost>

 

虚拟域名到此已经配置好了。接下来可以进入主题。


cookie可以跨二级域名访问,但session不能跨域访问,因此想要实现单点登录,可以尝试的方案有:


采用cookie传session_id,采用数据库保存session变量。


cookie跨二级域名访问,很容易实现,只要设置domain即可,参考代码:


'session' => array (

              'class' => 'application.components.MCCDbHttpSession',

                                     'cookieParams'=>array('domain'=>'.meztalks.com','lifetime'=>0,'path'=>'/'),

                    'connectionID' => 'db',

                    'sessionTableName' => 't_db_session',

                ),

采用数据库保存session,参考Yii自带的CDbHttpSession类,有特许需要,可以重写该类继承CDbHttpSession,重写openSession(),readSession(),writeSession(),destroySession().