简体   繁体   中英

How to store session in Redis using Zend 2

One of our applications has 2 server instances. We used Redis to access the session for both servers. When I logged-in in the site by using the email and password, I was redirected to login page again and I had to enter again the credentials so that I can access the modules. Generally, I had to log in two times.

This is the code in the Login Controller and both servers have the same code:

public function indexAction()
{
    $form = new LoginForm();
    $form->get('submit')->setValue('Login');
    $messages = null;
    //considering redis() and server were declared already
    $redis = $this->redis();
    $server = $this->getServer();
    $request = $this->getRequest();

    if ($request->isPost()) {

        $form->setInputFilter(new LoginFilter($this->getServiceLocator()));
        $form->setData($request->getPost());
        if ($form->isValid()) {

            $data = $form->getData();
            $admin = 0; 
            $user = $this->getEntityManager()->getRepository('\Admin\Entity\User');

            $userDetail = $user->getUseCompanyByUsername($data['email']);


            if(isset($userDetail) && !empty($userDetail)){
                $companyCompanyTypeRepo = $this->getEntityManager()->getRepository('\Admin\Entity\CompanyCompanyType');
                $companyCompanyType = $companyCompanyTypeRepo->getCompanyCompanyTypeByCompanyId($userDetail[0]['company_id']);

                foreach ($companyCompanyType as $key) {
                    if(strtolower($key['name'])=='admin'){
                       $admin=1; 
                    }
                }
                // begin here
                if($admin==1){
                    $authService = $this->getServiceLocator()->get('Zend\Authentication\AuthenticationService');

                    $adapter = $authService->getAdapter();
                    $adapter->setIdentityValue($data['email']); 
                    $adapter->setCredentialValue($data['password']); 
                    $authResult = $authService->authenticate();

                    if ($authResult->isValid()) {
                        $identity = $authResult->getIdentity();
                        $authService->getStorage()->write($identity);
                        $time = 1209600; // 14 days 1209600/3600 = 336 hours => 336/24 = 14 days
                        if ($data['rememberme']) {
                            $sessionManager = new \Zend\Session\SessionManager();
                            $sessionManager->rememberMe($time);
                        }
                        //store user info in session
                        $this->sessionContainer = new Container('user_info');
                        $this->sessionContainer->user_info = $userDetail;


                        if ($redis->hasItem('user_' . $data['email'] .'_' . $server)) {

                            return $this->redirect()->toRoute('home', array('controller' => 'index', 'action' => 'index'));

                        } else {

                            $redis->getOptions()->setTtl(7200);
                            $redis->setItem('user_' . $data['email'] .'_' . $server, serialize($this->sessionContainer->user_info));

                        }



                    }

                    foreach ($authResult->getMessages() as $message) {
                        $messages .= "$message\n"; 
                    }   
                }    
                else
                {
                    $messages="The credential supplied has no access to this portal.";
                }
                // end here
            }else{
                $messages="Your authentication credentials are not valid.";  
            }
        }
    }

    $view =  new ViewModel(array(
            'error' => 'Your authentication credentials are not valid',
            'form'    => $form,
            'messages' => $messages,
         ));

    return $view;
}

Do you have any idea what could go wrong? This is new to me. Thank you so much for your help.

So basically, using Redis for session storage does not work this way at all...

First problem you have is that redis is not used to store sessions, it is used to store a copy of the user details for a given time:

$redis->getOptions()->setTtl(7200);
$redis->setItem('user_' . $data['email'] .'_' . $server, serialize($this->sessionContainer->user_info));

So if it works, it only means you've always been directed on the same server, or your php.ini is also configured to write in a redis or memcached server.

For the "one every two logins", if you follow your code it comes from the fact that the first time around the cache is empty, therefore going into the else (code above), and adding the details to the cache. Second time, the details are cached, so going in the if and getting redirected.

You can have a look at this digital ocean tutorial to use redis for php sessions storage and make sure you do not override these settings in a Zend Session configuration (either in your configuration files or any Module class used in your application.

Then you will be able to remove this cache that does not actually work properly, and definitely not the way you think it should.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM