Skip to content

Customer Data

In Checkout the customer data is manipulated using ajax requests.

This is generally fine and allows dynamic updates without refreshing pages which would be jarring to most customers.

An issue however can arise when using any request other than GET or OPTIONS.

If you have a custom ajax request in checkout that performs any option other than those listed above e.g. POST/DELETE/PATCH, this will remove all customer data in checkout.

This means that any error message that appears in checkout will disappear almost instantly.

It should be noted that this appears to have been fixed in version 2.4, link at the bottom of this document

Possible Cause

Process Method

The cause for this issue could be from the Magento\Framework\App\PageCache\Version::process method. This method is called on basically every request through a plugin in the PageCache module, Magento\PageCache\Model\App\FrontController\BuiltinPlugin::aroundDispatch.

The process method:

    /**
     * Handle private content version cookie
     * Set cookie if it is not set.
     * Increment version on post requests.
     * In all other cases do nothing.
     *
     * @return void
     */
    public function process()
    {
        if ($this->request->isPost()) {
            $publicCookieMetadata = $this->cookieMetadataFactory->createPublicCookieMetadata()
                ->setDuration(self::COOKIE_PERIOD)
                ->setPath('/')
                ->setSecure($this->request->isSecure())
                ->setHttpOnly(false);
            $this->cookieManager->setPublicCookie(self::COOKIE_NAME, $this->generateValue(), $publicCookieMetadata);
        }
    }
Seems to remove all cookies, customer data in checkout is store in localStorage and not the database, which effectively removes all data in checkout (such as shipping data).

Validate Request Method

Another possible cause can be the validateRequest method in Magento\Framework\App\Request\CsrfValidator.

This method:

private function validateRequest(
        HttpRequest $request,
        ActionInterface $action
    ): bool {
        $valid = null;
        if ($action instanceof CsrfAwareActionInterface) {
            $valid = $action->validateForCsrf($request);
        }
        if ($valid === null) {
            $valid = !$request->isPost()
                || $request->isAjax()
                || $this->formKeyValidator->validate($request);
        }

        return $valid;
    }
will mark any request invalid if it is a post request that does not include an isAjax parameter.

Solutions

The quickest solution is just to upgrade the version of magento if possible.

If that is not possible, because of complex interactions with modules etc, then the ajax request can be passed through REST to a webapi.xml defined model or controller.

Alternatively you can just pass the isAjax parameter and then if the request failed through csrf it will now pass.

If the issue was from the process method destroying your cookies then you will need to use the webapi method outlined.

References

GitHub Issue