在Zend_Auth登录时创建的重复数据库会话

时间:2011-07-20 19:03:22

标签: zend-auth zend-acl zend-session

我一定是做错了。我似乎无法在网络上的任何地方找到我的问题的答案,这通常意味着解决方案非常简单,没有人需要答案。

我正在使用数据库来存储我的会话。我把它设置在我的引导程序中:


    protected function _initDBSessions(){
        $resource = $this->getPluginResource('db'); //from config.ini?
        $db = $resource->getOptions(); 
        $adapter = new Zend_Db_Adapter_Pdo_Mysql($db["params"]);

        Zend_Db_Table_Abstract::setDefaultAdapter($adapter); 
        $config = array('name'=>'sessions','primary'=>'id','modifiedColumn'=>'modified','dataColumn'=>'data','lifetimeColumn'=>'lifetime');
        $options = array(   
                "strict"=>FALSE,
                "name"=>"eCubed",
                "use_cookies"=>FALSE
                );
        Zend_Session::setOptions($options);
        Zend_Session::setSaveHandler(new Zend_Session_SaveHandler_DbTable($config));
    }

我的引导程序中的下一步是我的插件设置


    protected function _initPlugins(){
        Zend_Controller_Front::getInstance()->registerPlugin(new Acl_Acl());
    }

我的Acl_Acl看起来像这样:


    class Acl_Acl extends Zend_Controller_Plugin_Abstract{

        public function preDispatch(Zend_controller_request_abstract $request){
            $acl = new Zend_Acl();

            //add roles
            $acl->addRole(new Zend_Acl_Role(Acl_Levels::$GUEST));
            $acl->addRole(new Zend_Acl_Role(Acl_Levels::$BASIC),Acl_Levels::$GUEST);
            $acl->addRole(new Zend_Acl_Role(Acl_Levels::$SHOP),Acl_Levels::$BASIC);
            $acl->addRole(new Zend_Acl_Role(Acl_Levels::$OFFICE),Acl_Levels::$SHOP);
            $acl->addRole(new Zend_Acl_Role(Acl_Levels::$EXECUTIVE),Acl_Levels::$OFFICE);
            $acl->addRole(new Zend_Acl_Role(Acl_Levels::$OWNER));
            $acl->addRole(new Zend_Acl_Role(Acl_Levels::$ADMIN),Acl_Levels::$OWNER);

            //add resources
            $acl->addResource("index");
            $acl->addResource("authenticate");
            $acl->addResource("error");
            $acl->addResource("employees");
            $acl->addResource("mold");
            $acl->addResource("search");
            $acl->addResource("shop");
            $acl->addResource("user");

            //access rules
            $acl->allow(null,array('index','error','authenticate')); //default resources


            //Guest member access
            $acl->allow(Acl_Levels::$GUEST,'mold',array('index','list-molds'));
            $acl->allow(Acl_Levels::$GUEST,'user',array('index','login','new-profile','my-profile'));

            //SHOP Member Access
            $acl->allow(Acl_Levels::$BASIC,'mold',array('get-mold','get-part','get-order','get-orders','get-parts','print-mold-labels','print-part-labels'));
            $acl->allow(Acl_Levels::$BASIC,'user',array('my-profile','profile'));

            //OFFICE Member Access

            //EXECUTIVE Member Access

            //OWNER Member Access

            //ADMIN Member Access

            //current user
            if(Zend_Auth::getInstance()->hasIdentity()){
                $level = Zend_Auth::getInstance()->getIdentity()->level;
            } else {
                $level = Acl_Levels::$GUEST;
            }

            $conroller = $request->controller;
            $action = $request->action;

            try {
                if(!$acl->isAllowed($level,$conroller,$action)){
                        $request->setControllerName('application-error');
                        $request->setActionName('not-authorized');
                }
            } catch (Exception $e){ 
                $request->setControllerName("application-error");
                $request->setActionName("error");

                $error = new Zend_Controller_Plugin_ErrorHandler();
                $error->type = Zend_Controller_Plugin_ErrorHandler::EXCEPTION_OTHER;
                $error->request = clone($request);
                $error->exception = $e;
                $request->setParam('error_handler',$error);
            }

        }   
    }

我的身份验证控制器具有以下操作:


    public function loginAction(){
            $this->_helper->viewRenderer->setNoRender(TRUE);

            $loginForm = new Form_Login();
            $form = $loginForm->getLoginForm();
            $form->setAction("/authenticate/login");

            if($this->getRequest()->isPost()){
                if($form->isValid($_POST)){
                    $email = $form->getValue('email');
                    $pass = $form->getValue('password');

                    $authAdapter = $this->getAuthAdapter();
                    $authAdapter    ->setIdentity($email)
                                    ->setCredential($pass);
                    $result = Zend_Auth::getInstance()->authenticate($authAdapter);

                    if($result->isValid()){
                        $omit = array('password','timestamp','temp_password','active','created');
                        $identity = $authAdapter->getResultRowObject(NULL,$omit);

                        $authStorage = Zend_Auth::getInstance()->getStorage();
                        $authStorage->write($identity);

                        $nickname = $identity->nickname ? $identity->nickname : $identity->first_name;

                        $this->_helper->flashMessenger("Welcome back $nickname");

                        //Zend_Debug::dump($identity); exit;
                        $this->_redirect("/"); 

                    } else {
                        $this->_helper->flashMessenger("Unable to log you in.  Please try again");
                        $this->_redirect("/");
                    }
                }
            }
        }

我的数据库结构: id:int 修改:int 寿命:int 数据:文字

一切都很好,对吗?好吧,不......

首先,每当未登录的用户刷新或导航到某个页面时,都会创建一个会话。这是可以接受的,我猜......

我遇到的问题是,当我最终登录时,我可以看到数据库完美地存储了Zend_Auth标识和Flashmessenger,但是......

......如果没有登录用户导航网站,也会在数据库中创建一个幻像行....

这使得身份验证变得不可能,因为当用户被重定向到“Profile”页面时,例如,Zend正在查看绝对没有数据的幻像会话数据!

以下是存储在Zend_Session数据库表中的信息,作为存储内容的证据:

Zend_Auth的|一个:1:{S:7: “存储”,O:8: “stdClass的”:7:{S:2: “ID”,S:1: “2”; S:5:”电子邮件 “; S:17:” WES @ * *** .COM “; S:10:” 如first_name “; S:6:” 韦斯利“; S: 9: “姓氏”; S:7: “的 * ”; S:5: “电平”; S:5: “基本”,S:8:“昵称“; s:3:”Wes“; s:9:”lastlogin“; s:19:”2011-07-14 19:30:36“;}} __ ZF | a:1:{s:14:”FlashMessenger “;一个:1:{S:4:” ENNH “; I:1;}} FlashMessenger |一个:1:{S:7:” 默认 “;一个:1:{I 0,S:16:”欢迎回来Wes“;}}

这让我疯了2天了。我的印象是Zend_Session只会自动使用1个会话来存储数据,但是这些多个条目让我很生气!!

我希望我已经给了别人足够的信息来解决问题。

1 个答案:

答案 0 :(得分:1)

我发现了这个问题......

正如所料,解决方案是一个简单的错字......

我不知道如何在这里戏剧性地写出答案,但问题是......

我的数据库表,称为“会话”,其数据类型错误。

id列的数据类型设置为“int”(11)

而应将其设置为“char”(32)

DUH!我希望我花在这个问题上的4天可以帮助其他人!