Customers are being logged out when they click 'Go to checkout' before the basket page has fully loaded.

It also looks like guests are having their basket emptied when they follow the same process.

We're running Magento 2.2.5 and using Mageplaza_Osc 2.5.0.

  • Please check by disabling Magento caches. – Vish Aug 10 at 9:26
  • Is checkout and normal pages different, I mean HTTP and HTTPS? – kunj Aug 10 at 9:27
  • @vish the same thing happens with caching disabled – Zaq Mughal Aug 10 at 9:33
  • @kunj all pages using https – Zaq Mughal Aug 10 at 9:34
  • seems session is being cleared out when user goesfrom cart to OSC page. have you any idea that if there any other module working on session in its observer files? – shashank Aug 10 at 9:35

Turns out this is a known Magento 2 bug with many stores suffering from the same problem.

I initially reported that the problem happens when you click 'Go to checkout' before the basket page had fully loaded. What is actually happening is that concurrent (quick reload) requests on checkout cause cart to empty.

This can be triggered by a double click on the 'Go to checkout' button or multiple refreshes on the checkout page.

Below is a fix that has been tested on Magento 2.2.5. Please note that this is a temporary fix (I wouldn't normally edit core files) until Magento release a full fix.

In vendor/magento/framework/Session/SessionManager.php replace the regenerateId() function with:

public function regenerateId()
    {
        if (headers_sent()) {
            return $this;
        }

        if ($this->isSessionExists()) {
            $oldSessionId = session_id();            
            session_regenerate_id();   //regen the session
            $new_session_id = session_id();

            $_SESSION['new_session_id'] = $new_session_id;

            // Set destroy timestamp
            $_SESSION['destroyed'] = time();

            // Write and close current session;
            session_commit();
            $oldSession = $_SESSION;   //called after destroy - see destroy!
            // Start session with new session ID
            session_id($new_session_id);
            ini_set('session.use_strict_mode', 0);
            session_start();
            ini_set('session.use_strict_mode', 1);
            $_SESSION = $oldSession;
            // New session does not need them
            unset($_SESSION['destroyed']);
            unset($_SESSION['new_session_id']);  
        } else {
            session_start();
        }
        $this->storage->init(isset($_SESSION) ? $_SESSION : []);

        if ($this->sessionConfig->getUseCookies()) {
            $this->clearSubDomainSessionCookie();
        }
        return $this;
    }

Then in the same file, replace the start() function with:

public function start()
    {
        if (!$this->isSessionExists()) {
            \Magento\Framework\Profiler::start('session_start');

            try {
                $this->appState->getAreaCode();
            } catch (\Magento\Framework\Exception\LocalizedException $e) {
                throw new \Magento\Framework\Exception\SessionException(
                    new \Magento\Framework\Phrase(
                        'Area code not set: Area code must be set before starting a session.'
                    ),
                    $e
                );
            }

            // Need to apply the config options so they can be ready by session_start
            $this->initIniOptions();
            $this->registerSaveHandler();
            if (isset($_SESSION['new_session_id'])) {
             // Not fully expired yet. Could be lost cookie by unstable network.
             session_commit();
             session_id($_SESSION['new_session_id']);
             }
            // potential custom logic for session id (ex. switching between hosts)
            $this->setSessionId($this->sidResolver->getSid($this));
            session_start();
            if (isset($_SESSION['destroyed'])) {
               if ($_SESSION['destroyed'] < time()-300) {
                   $this->destroy(['clear_storage' => true]);

               }
            }
            $this->validator->validate($this);

            register_shutdown_function([$this, 'writeClose']);

            $this->_addHost();
            \Magento\Framework\Profiler::stop('session_start');
        }
        $this->storage->init(isset($_SESSION) ? $_SESSION : []);
        return $this;
    }

Fix taken from https://github.com/magento/magento2/issues/12362.

Your Answer

 
discard

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.