-
Notifications
You must be signed in to change notification settings - Fork 9.4k
Add Inline Form Key Updater to Page Cache | Fix Issue #13746 #27647
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Hi @nicolasddev. Thank you for your contribution
For more details, please, review the Magento Contributor Guide documentation. |
|
Hi @nicolasddev, @magento run all tests |
| { | ||
| public function afterToHtml(\Magento\Framework\View\Element\FormKey $subject, $result) | ||
| { | ||
| return $result.$this->getInlineJavaScript(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like this shouldn't happen in case if FPC is disabled. Am I correct?
| <script> | ||
| var formKey = (function () { | ||
|
|
||
| var value = "; " + document.cookie; | ||
| var parts = value.split("; " + 'form_key' + "="); | ||
|
|
||
| if (parts.length == 2) { | ||
| return parts.pop().split(";").shift(); | ||
| } | ||
|
|
||
| })(); | ||
| </script> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-
As Magento introduced CSP - we need to use something like this:
echo /* @noEscape */ $secureRenderer->renderTag('script', [], $scriptString, false); -
Seems like case with missing form_key cookie isn't covered here
magento2/app/code/Magento/PageCache/view/frontend/web/js/page-cache.js
Lines 120 to 123 in 9544fb2
if (!formKey) { formKey = generateRandomString(this.options.allowedCharacters, this.options.length); $.mage.cookies.set('form_key', formKey, options); } -
I think we need to remove following code as we basically replacing it with inline implementation
magento2/app/code/Magento/PageCache/view/frontend/web/js/page-cache.js
Lines 300 to 303 in 9544fb2
domReady(function () { $('body') .formKey(); });
| { | ||
| $uniqueId = uniqid(); | ||
|
|
||
| return '<script id="'.$uniqueId.'">document.getElementById("'.$uniqueId.'").previousSibling.value = formKey;</script>'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As Magento introduced CSP, we need to replace this code with something like this:
| echo /* @noEscape */ $secureRenderer->renderTag('script', [], $scriptString, false); |
|
The risk was set to |
|
Hi @nicolasddev, |
|
@nicolasddev I am closing this PR now due to inactivity. |
|
Hi @nicolasddev, thank you for your contribution! |
Description (*)
This fix ensures that form keys are updated on frontend pages as soon as the form_key input field is loaded in order to prevent delays resulting in the "Invalid Form Key. Please refresh the page" error.
A script tag with a unique ID is being added and executed inline directly after each form_key input ensuring its value is updated as soon as possible.
An internally-developed extension using the same approach is running on one of our customer's production server preventing this issue from occurring. The issue was more frequently encountered on long category pages due to the fact that the HTML had to be downloaded in multiple packets.
This fix is provided by MageMontreal, a Magento Business Solution Partner.
Fixed Issue
Manual testing scenarios (*)
Comments
Before applying this fix, when a long page or a page requiring several resources was opened, the form keys on the page were not updated immediately as the below script hadn't been executed yet.
Script: Magento/PageCache/view/frontend/web/js/page-cache.js
As this fix makes sure that the form keys are each updated inline as soon as the content has been downloaded by the browser, the issue doesn't occur anymore.
Note: Uses pure JavaScript to ensure that the scripts are executed without having to wait for RequireJS or any dependencies.
Functional Requirement
Form key input fields must be integrated to the form through the Magento\Framework\View\Element\FormKey block which is best practice, in order to benefit from this fix/improvement.
Contribution checklist (*)