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);
}
}
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;
}
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.