Исправление SUPEE-9767/CE 1.9.3.3 - Проверка одной страницы - Проблема с регистрацией клиентов


При чистой, ванильной установке Magento 1.9.2.4, исправленной с помощью SUPEE-8788, SUPEE-9652 и SUPEE-9767, и с включенной настройкой "Включить проверку ключа формы при оформлении заказа", после успешной регистрации нового клиента при оформлении заказа на одной странице по умолчанию новый клиент не создается и клиент не входит в систему, хотя заказ проходит нормально.

Отключение параметра "Включить проверку ключа формы при оформлении заказа" делает это снова работать. У кого-нибудь еще была эта проблема? Похоже, не имеет значения, какие способы доставки/оплаты используются.

С тех пор я пробовал это с новой, неизмененной установкой Magento 1.9.3.3, и, похоже, у нее та же проблема. При регистрации нового клиента через оформление заказа на одной странице ни один клиент не создается, даже если заказ проходит нормально, если включена настройка "Включить проверку ключа формы при оформлении заказа".

Author: Raphael at Digital Pianism, 2017-06-01

6 answers

Хорошо, вот реальное исправление ошибки, которое я придумал.

Отредактируйте /skin/frontend/base/default/js/opcheckout.js и отредактируйте метод setMethod(), заменив:

setMethod: function(){
    if ($('login:guest') && $('login:guest').checked) {
        this.method = 'guest';
        new Ajax.Request(
            this.saveMethodUrl,
            {method: 'post', onFailure: this.ajaxFailure.bind(this), parameters: {method:'guest'}}
        );
        Element.hide('register-customer-password');
        this.gotoSection('billing', true);
    }
    else if($('login:register') && ($('login:register').checked || $('login:register').type == 'hidden')) {
        this.method = 'register';
        new Ajax.Request(
            this.saveMethodUrl,
            {method: 'post', onFailure: this.ajaxFailure.bind(this), parameters: {method:'register'}}
        );
        Element.show('register-customer-password');
        this.gotoSection('billing', true);
    }
    else{
        alert(Translator.translate('Please choose to register or to checkout as a guest').stripTags());
        return false;
    }
    document.body.fire('login:setMethod', {method : this.method});
},

С помощью:

setMethod: function(){
    var formKey = $('checkout-step-login').select('[name=form_key]')[0].value;
    if ($('login:guest') && $('login:guest').checked) {
        this.method = 'guest';
        new Ajax.Request(
            this.saveMethodUrl,
            {method: 'post', onFailure: this.ajaxFailure.bind(this), parameters: {method:'guest', form_key:formKey}}
        );
        Element.hide('register-customer-password');
        this.gotoSection('billing', true);
    }
    else if($('login:register') && ($('login:register').checked || $('login:register').type == 'hidden')) {
        this.method = 'register';
        new Ajax.Request(
            this.saveMethodUrl,
            {method: 'post', onFailure: this.ajaxFailure.bind(this), parameters: {method:'register', form_key:formKey}}
        );
        Element.show('register-customer-password');
        this.gotoSection('billing', true);
    }
    else{
        alert(Translator.translate('Please choose to register or to checkout as a guest').stripTags());
        return false;
    }
    document.body.fire('login:setMethod', {method : this.method});
},

Это сделает это, пока мы ждем версии 2 патча

 36
Author: Raphael at Digital Pianism, 2017-06-02 07:54:35

Когда вы выбираете зарегистрироваться и продолжить, скрипт JS вызывает checkout.setMethod(), который находится в skin/frontend/base/default/js/opcheckout.js. Оттуда мы видим, что он отправляет запрос AJAX POST на this.saveMethodUrl, но единственный параметр, который он передает, - это method. Если мы посмотрим на Mage_Checkout_OnepageController::saveMethodAction, который является целью этого запроса AJAX, мы увидим, что патч добавил:

if ($this->isFormkeyValidationOnCheckoutEnabled() && !$this->_validateFormKey()) {
        return;
}

Поскольку _validateFormKey ищет параметр form_key в запросе, и поскольку запрос JS setMethod не отправил его при выполнении запроса AJAX, он просто возвращается раньше и ничего не делая. Вернемся к функции setMethod, и мы увидим, что, поскольку она ничего не пытается сделать с возвращаемым значением, больше ничего не происходит, и JS продолжается. На данный момент JS установил this.method = 'register', но цитата не была обновлена, поэтому checkout_method является "гостем" по умолчанию.

Поскольку JS знает, что клиент выбрал регистрацию, он отображает поля пароля, поэтому на первый взгляд это выглядит так, как будто вы регистрируетесь. Но что касается PHP-стороны, это гостевая проверка, так что не создает клиента после завершения оформления заказа.

Редактировать: самое простое исправление - закомментировать эти три строки из saveMethodAction. Более правильное/сложное решение заключается в том, что setMethod следует захватить form_key со страницы и отправить его с запросом AJAX.

 15
Author: Peter O'Callaghan, 2017-06-01 20:26:26

Полные кредиты достаются Питеру за решение! Я хотел бы указать на пошаговую инструкцию, что нужно изменить.

Перейдите к app/code/core/Mage/Checkout/controllers/OnepageController.php

Найдите:

 public function saveMethodAction()
{
    if ($this->_expireAjax()) {
        return;
    }

    if ($this->isFormkeyValidationOnCheckoutEnabled() && !$this->_validateFormKey()) {
        return;
    }

Закомментируйте строку тегами /**/.

 public function saveMethodAction()
{
    if ($this->_expireAjax()) {
        return;
    }

    /*if ($this->isFormkeyValidationOnCheckoutEnabled() && !$this->_validateFormKey()) {
        return;
    }*/
 3
Author: Icon, 2017-06-01 21:24:33

Хороший момент для начала:

Исправление безопасности SUPEE-9767 - Возможные проблемы?

Вам необходимо обновить файлы шаблонов. Пожалуйста, обратите внимание, что с момента выпуска этого патча осталось всего несколько часов, и на данный момент нам приходится иметь дело с тем, что является общедоступным. Я почти уверен, что в ближайшие дни все прояснится.

РЕДАКТИРОВАТЬ: Спасибо, что проголосовали против! Мне жаль, что я не могу дать решение через 8 часов после выпуска этого патча.

 1
Author: ADDISON74, 2017-06-01 18:13:14

Спасибо за патч @ Raphael в Digital Pianism.

Для удобства я создал различие, чтобы вы могли быстро применить патч.

 skin/frontend/base/default/js/opcheckout.js | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/skin/frontend/base/default/js/opcheckout.js b/skin/frontend/base/default/js/opcheckout.js
index 8935793af..9ccbe61a9 100644
--- a/skin/frontend/base/default/js/opcheckout.js
+++ b/skin/frontend/base/default/js/opcheckout.js
@@ -165,20 +165,21 @@ Checkout.prototype = {
     },

     setMethod: function(){
+        var formKey = $('checkout-step-login').select('[name=form_key]')[0].value;
         if ($('login:guest') && $('login:guest').checked) {
             this.method = 'guest';
-            var request = new Ajax.Request(
+            new Ajax.Request(
                 this.saveMethodUrl,
-                {method: 'post', onFailure: this.ajaxFailure.bind(this), parameters: {method:'guest'}}
+                {method: 'post', onFailure: this.ajaxFailure.bind(this), parameters: {method:'guest', form_key:formKey}}
             );
             Element.hide('register-customer-password');
             this.gotoSection('billing', true);
         }
         else if($('login:register') && ($('login:register').checked || $('login:register').type == 'hidden')) {
             this.method = 'register';
-            var request = new Ajax.Request(
+            new Ajax.Request(
                 this.saveMethodUrl,
-                {method: 'post', onFailure: this.ajaxFailure.bind(this), parameters: {method:'register'}}
+                {method: 'post', onFailure: this.ajaxFailure.bind(this), parameters: {method:'register', form_key:formKey}}
             );
             Element.show('register-customer-password');
             this.gotoSection('billing', true);
 1
Author: Brainski, 2017-06-27 09:09:51

Версия 2 исправления SUPEE-9767 была выпущена ранее сегодня вместе с Magento CE 1.9.3.4. Версия 2 исправляет ряд проблем, в том числе эту ошибку регистрации при оформлении заказа.

Вы можете обновить до последней версии (1.9.3.4) или отменить версию V1, а затем применить версию 2 исправления. Любой из вариантов решит проблему.

Официальное изменение в версии 2 фактически совпадает с описанным Питером О'Каллаганом, удалив три строки, добавленные в Mage_Checkout_OnepageController::saveMethodAction.

 1
Author: Ryan Hoerr, 2017-07-12 23:22:50