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

19

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

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

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

RickyMage123
источник

Ответы:

36

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

Отредактируйте /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});
},

Это будет сделано, пока мы ждем v2 патча

Рафаэль в цифровом пианизме
источник
Ницца. Мне было лень разрабатывать прототип, чтобы найти подходящее поле ввода.
Питер О'Каллаган
@ PeterO'Callaghan, да, прототип труден для работы, когда вы привыкли к jQuery ^^
Рафаэль из Digital
1
Что происходит, когда у вас нет элемента с именем «form_key» в вашей кассе в этот момент? Насколько велики шансы, которые произойдут?
Арьен
1
@paj спасибо, что дали мне знать. Внедрил его для нескольких магазинов без проблем
Arjen Miedema
1
@RaphaelatDigitalPianism: я попробовал ваш путь, но это не помогло мне, вы понимаете?
Анураг
15

Когда вы выбираете зарегистрироваться и продолжить, 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параметр в запросе, и поскольку setMethodзапрос JS не отправил его, когда он сделал запрос AJAX, он просто возвращается рано и ничего не делает. Вернемся к setMethodфункции, и мы видим, что, поскольку она ничего не пытается сделать с возвращаемым значением, ничего не происходит, и JS продолжается. На данный момент JS настроен, this.method = 'register'но цитата не была обновлена, так checkout_methodчто по умолчанию это «гость».

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

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

Питер О'Каллаган
источник
Не могли бы вы указать путь, по которому мы можем найти: this-> isFormkeyValidationOnCheckoutEnabled () &&! $ This -> _ validateFormKey
Icon
skin / frontend / base / default / js / opcheckout.js не содержит этой функции.
Иконка
2
Фрагмент кода, проверяющий form_key от app/code/core/Mage/Checkout/controllers/OnepageController.php. Это вызвано тем, что JS делает запрос, не отправляя ключ form_key. Это ошибка с патчем. Я подозреваю, что будет v2.
Питер О'Каллаган
2
Или до исправления v2, просто отключите параметр «Система / Конфигурация / Администратор -> Безопасность ->« Включить проверку ключа формы при оформлении заказа »на 0». Это приведет к уведомлению, но после исправления v2 мы сможем повторно включить его
Jeroen
1
Спасибо, что копали немного глубже, Питер. Надеюсь, кто-то из Magento обнаружит это или заметит сообщение об ошибке, и мы получим v2.
RickyMage123
3

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

Перейдите в приложение / 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;
    }*/
Икона
источник
2
Это неправильно, вы комментируете тот, который добавил патч. Насколько я знаю об этом патче, js запрос должен отправить form keyвместо. Мы должны сообщить об этой ошибке (патче) основной команде magento.
Адарш Хатри
@AdarshKhatri Это может быть неправильно, но это работает! и да, команда magento должна знать об этом. Двойное сообщение им, если можете.
Иконка
2
@AdarshKhatri Я согласен с тобой. Комментирование этих двух строк устраняет проблему, но устраняет также цель патча. У меня та же проблема, и я не могу понять, как ее исправить на данный момент ...
DarkCowboy
Вместо того, чтобы комментировать, isFormkeyValidationOnCheckoutEnabled()вы можете просто отключить настройку в админке, но лучшее решение - это Raphaels: magento.stackexchange.com/a/177125/2671
DanCarlyon
@DanCarlyon То, что когда-либо делал Рафаэль, - отличная работа. Я только что дал инструкцию для краткосрочного исправления, предложенного Питером, за несколько дней до того, как Мадженто признал, что есть проблема. Я согласен, что это не идеальное решение, а скорее исправление, так же как и отключение форм-ключей из серверной части.
Иконка
1

Хорошая точка для начала:

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

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

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

ADDISON74
источник
3
Да, я просмотрел все файлы шаблонов в установке, где обнаружил проблему. Я обновил вопрос выше - на тестовой ванильной установке Magento 1.9.3.3 без изменений у меня, похоже, возникла та же проблема. Тестовая установка 1.9.2.4 тоже использовала пакет / тему по умолчанию (свежий, неизмененный).
RickyMage123
Я пробовал с 1.7.0.2 и то же самое, клиенты никогда не регистрируются, когда ключи форм включены.
Иконка
1
Я проведу некоторые исследования, сравнивая 1.9.2.4 с 1.9.3.3, и посмотрю, в чем различия. Я не установил с нуля 1.9.3.3 еще. Я опубликую отчет по указанной ссылке выше.
ADDISON74
2
Будет ли обновление, если я найду проблему; Я получил сообщение об ошибке в Magento, так как это, похоже, проблема с неизмененной установкой 1.9.3.3.
RickyMage123
1
Этот баг-трекер в Magento - не способ сообщить, он бесполезен. Я делал это раньше, предлагая решения, и в коде ничего не изменилось. Никто не слушает там, но они слушают в Magento 2! Я всегда находил решения в других местах, кроме сайта Magento. Я советую сделать несколько тестов перед обновлением ваших производственных сайтов. С новыми проблемами, я думаю, мы увидим новое обновление раньше, чем мы думаем. То же самое произошло между 1.9.3.0 и 1.9.3.1.
ADDISON74
1

Спасибо за патч @ Рафаэль в Digital Pianism.

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

 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);
Brainski
источник
1

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

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

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

Райан Херр
источник