2

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.

10
  • Please check by disabling Magento caches.
    – Vish V
    Aug 10, 2018 at 9:26
  • Is checkout and normal pages different, I mean HTTP and HTTPS?
    – kunj
    Aug 10, 2018 at 9:27
  • @vish the same thing happens with caching disabled
    – Zaq Mughal
    Aug 10, 2018 at 9:33
  • @kunj all pages using https
    – Zaq Mughal
    Aug 10, 2018 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? Aug 10, 2018 at 9:35

1 Answer 1

3

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

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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