我正在将商店从magento 1迁移到magento 2,并且它将它与Quickbooks Desktop集成在MQC远程桌面上。
我在m1和m2上都使用了consolibyte。它也在m2上工作。然后我不得不放下这个任务并将magento更新到2.3.0。
现在,当我尝试在远程桌面上的Web连接器中更新我的magento 2应用程序时,它给出了以下错误:
"Version:
Not provided by service
Message:
Authentication failed
Description:
QBWC1012: Authentication failed due to following error message.
The request failed with an empty response. See QWCLog for more details. Remember to turn logging on."
日志看起来像这样:
"20190213.06:57:36 UTC : QBWebConnector.WebServiceManager.DoUpdateSelected() : updateWS() for application = 'Sansha 2 France 1.0' has STARTED
20190213.06:57:36 UTC : QBWebConnector.RegistryManager.getUpdateLock() : HKEY_CURRENT_USER\Software\Intuit\QBWebConnector\UpdateLock = FALSE
20190213.06:57:36 UTC : QBWebConnector.RegistryManager.setUpdateLock() : HKEY_CURRENT_USER\Software\Intuit\QBWebConnector\UpdateLock has been set to True
20190213.06:57:36 UTC : QBWebConnector.RegistryManager.setUpdateLock() : ********************* Update session locked *********************
20190213.06:57:36 UTC : QBWebConnector.SOAPWebService.instantiateWebService() : Initiated connection to the following application.
20190213.06:57:36 UTC : QBWebConnector.SOAPWebService.instantiateWebService() : AppName: Sansha 2 France 1.0
20190213.06:57:36 UTC : QBWebConnector.SOAPWebService.instantiateWebService() : AppUniqueName (if available): Sansha 2 France 1.0
20190213.06:57:36 UTC : QBWebConnector.SOAPWebService.instantiateWebService() : AppURL: https://eurostore.magento2.sansha.com/quickbooks/api
20190213.06:57:36 UTC : QBWebConnector.SOAPWebService.do_serverVersion() : *** Calling serverVersion().
20190213.06:57:36 UTC : QBWebConnector.SOAPWebService.do_serverVersion() : Actual error received from web service for serverVersion call: <The request failed with an empty response.>. For backward compatibility of all webservers, QBWC will catch all errors under app-not-supporting-serverVersion.
20190213.06:57:36 UTC : QBWebConnector.SOAPWebService.do_serverVersion() : This application does not contain support for serverVersion. Allowing update operation for backward compatibility.
20190213.06:57:36 UTC : QBWebConnector.SOAPWebService.do_clientVersion() : *** Calling clientVersion() with following parameter:<productVersion="2.2.0.71">
20190213.06:57:37 UTC : QBWebConnector.SOAPWebService.updateWS() : Actual error received from web service for clientVersion call: <The request failed with an empty response.>. For backward compatibility of all webservers, QBWC will catch all errors under app-not-supporting-clientVersion.
20190213.06:57:37 UTC : QBWebConnector.SOAPWebService.do_clientVersion() : This application does not contain support for clientVersion. Allowing update operation for backward compatibility.
20190213.06:57:37 UTC : QBWebConnector.SOAPWebService.do_authenticate() : Authenticating to application 'Sansha 2 France 1.0', username = 'sansha'
20190213.06:57:37 UTC : QBWebConnector.SOAPWebService.do_authenticate() : *** Calling authenticate() with following parameters:<userName="sansha"><password=<MaskedForSecurity>
20190213.06:57:37 UTC : QBWebConnector.SOAPWebService.do_authenticate() : QBWC1012: Authentication failed due to following error message.
The request failed with an empty response.
More info:
StackTrace = at System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage message, WebResponse response, Stream responseStream, Boolean asyncCall)
at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters)
at QBWebConnector.localhost.WCWebServiceDoc.authenticate(String strUserName, String strPassword)
at QBWebConnector.localhost.WCWebService.authenticate(String strUserName, String strPassword)
at QBWebConnector.SOAPWebService.authenticate(String UserName, String Password)
at QBWebConnector.WebService.do_authenticate(String& ticket, String& companyFileName)
Source = System.Web.Services
20190213.06:57:37 UTC : QBWebConnector.RegistryManager.setUpdateLock() : HKEY_CURRENT_USER\Software\Intuit\QBWebConnector\UpdateLock has been set to False
20190213.06:57:37 UTC : QBWebConnector.RegistryManager.setUpdateLock() : ********************* Update session unlocked *********************
20190213.06:57:37 UTC : QBWebConnector.WebServiceManager.DoUpdateSelected() : Update completed with errors. See log (QWClog.txt) for details.
"
我试图找到一个解决方案,但仍然没有运气。
SOAP服务器似乎工作:
"QuickBooks PHP DevKit Server v3.0 at /quickbooks/api/
(c) "Keith Palmer" <[email protected]>
Visit us at: http://www.ConsoliBYTE.com/
Use the QuickBooks Web Connector to access this SOAP server.
QuickBooks_WebConnector_Server::handle() parameters:
- $return = 1
- $debug = 1
Misc. information:
- Logging: 1
- Timezone: Europe/Paris (Auto-set: )
- Current Date/Time: 2019-02-14 08:09:29
- Error Reporting: 32767
SOAP adapter:
- QuickBooks_Adapter_Server_Builtin
Registered handler functions:
Array
(
[0] => __construct
[1] => authenticate
[2] => sendRequestXML
[3] => receiveResponseXML
[4] => connectionError
[5] => getLastError
[6] => closeConnection
[7] => serverVersion
[8] => clientVersion
)
Detected input:
Timestamp:
- 2019-02-14 08:09:29 -- process 0.27981"
这就是它的启动方式:
if(!\QuickBooks_Utilities::initialized($dsn)) {
\QuickBooks_Utilities::initialize($dsn);
\QuickBooks_Utilities::createUser($dsn, $qb_username, $qb_password);
}
$server = new \QuickBooks_WebConnector_Server($dsn, $this->_map, $this->_errmap, $this->_hooks);
$response = $server->handle(true, true);
有人遇到过这个问题吗?有人知道如何解决它。
问候
最后发现了这个问题。
重点是更新到magento 2.3会破坏HTTP POST请求,或至少在更新之前它们的工作方式,请参阅https://magento.stackexchange.com/questions/253414/magento-2-3-upgrade-breaks-http-post-requests-to-custom-module-endpoint。
我使用https://github.com/consolibyte/quickbooks-php/blob/master/dev/dev_qbwc_tester.php来测试请求,表单密钥无效。要解决此问题,您的控制器必须实现CsrfAwareActionInterface。
为了防止magento在初始化QBWC服务器之后尝试设置cookie并重写头文件,您必须在初始化SOAP服务器之后阻止代码。我放了一个die()之后,不确定是最好的解决方案,但认证工作(这是我的主要问题)。
控制器中的最终代码如下所示:
<?php
namespace Sansha\Quickbooks\Controller\Api;
use Magento\Framework\App\CsrfAwareActionInterface;
use Magento\Framework\App\RequestInterface;
use Magento\Framework\App\Request\InvalidRequestException;
class Index extends \Magento\Framework\App\Action\Action implements CsrfAwareActionInterface
{
protected $resultPageFactory;
protected $_map = array();
protected $_hooks = array();
protected $_errmap = array();
protected $_helper_config;
protected $_helper_data;
protected $_helper_api;
protected $_logger;
/**
* Constructor
*
* @param \Magento\Framework\App\Action\Context $context
* @param \Magento\Framework\View\Result\PageFactory $resultPageFactory
*/
public function __construct(
\Magento\Framework\App\Action\Context $context,
\Magento\Framework\View\Result\PageFactory $resultPageFactory,
\Sansha\Quickbooks\Helper\QbConfig $helperConfig,
\Sansha\Quickbooks\Helper\QbData $helperData,
\Sansha\Quickbooks\Helper\QbApi $helperApi,
\Sansha\Quickbooks\Logger\Logger $logger
) {
$this->resultPageFactory = $resultPageFactory;
$this->_helper_config = $helperConfig;
$this->_helper_data = $helperData;
$this->_helper_api = $helperApi;
$this->_logger = $logger;
parent::__construct($context);
}
/**
* Execute view action
*
* @return \Magento\Framework\Controller\ResultInterface
*/
public function execute()
{
if (function_exists('date_default_timezone_set'))
{
date_default_timezone_set('Europe/Paris');
}
$store_id = $this->_helper_data->getStoreId();
$dsn = $this->_helper_config->getDsn($store_id);
$qb_username = $this->_helper_config->getQbLogin($store_id)['username'];
$qb_password = $this->_helper_config->getQbLogin($store_id)['password'];
if(!\QuickBooks_Utilities::initialized($dsn)) {
\QuickBooks_Utilities::initialize($dsn);
\QuickBooks_Utilities::createUser($dsn, $qb_username, $qb_password);
}
$server = new \QuickBooks_WebConnector_Server($dsn, $this->_map, $this->_errmap, $this->_hooks);
$response = $server->handle(true, true);
die(); // stop code exectuon after server initialization
}
// below 2 functions will avoid breaking HTTP POST request
public function createCsrfValidationException(RequestInterface $request): ?InvalidRequestException
{
return null;
}
public function validateForCsrf(RequestInterface $request): ?bool
{
return true;
}