【问题标题】:401 Error "oauth_problem=nonce_used" Adding Products To Magento w/ Rest API401 错误“oauth_problem=nonce_used”将产品添加到 Magento w/Rest API
【发布时间】:2013-03-24 05:15:28
【问题描述】:

尝试使用 rest api 将产品添加到 Magento 时,返回 401 状态并返回“oauth_problem=nonce_used”消息。奇怪的是,这些产品仍然是进口的,但这真的让我很失望,因为我没有得到更新库存信息的产品 ID。

Magento 安装是全新的(crucialwebhost 安装程序)1.7.0.2,我使用的代码几乎是从 magento 网站复制和粘贴的...

$callbackUrl = '****';
$temporaryCredentialsRequestUrl = "*****/oauth/initiate?oauth_callback=".urlencode($callbackUrl);
$adminAuthorizationUrl = '*****/admin/oauth_authorize';
$accessTokenRequestUrl = '*****/oauth/token';
$apiUrl = '*****/api/rest';

$consumerKey = '*****';
$consumerSecret = '******';

try
{
$authType = ($_SESSION['state'] == 2) ? OAUTH_AUTH_TYPE_AUTHORIZATION : OAUTH_AUTH_TYPE_URI;
$oauthClient = new OAuth($consumerKey, $consumerSecret, OAUTH_SIG_METHOD_HMACSHA1, $authType);
$oauthClient->enableDebug();

if(!isset($_GET['oauth_token']) && !$_SESSION['state'])
{
  $requestToken = $oauthClient->getRequestToken($temporaryCredentialsRequestUrl);
  $_SESSION['secret'] = $requestToken['oauth_token_secret'];
  $_SESSION['state'] = 1;
  header('Location: '.$adminAuthorizationUrl.'?oauth_token='.$requestToken['oauth_token']);
  exit;
} else if($_SESSION['state'] == 1)
{
  $oauthClient->setToken($_GET['oauth_token'], $_SESSION['secret']);
  $accessToken = $oauthClient->getAccessToken($accessTokenRequestUrl);
  $_SESSION['state'] = 2;
  $_SESSION['token'] = $accessToken['oauth_token'];
  $_SESSION['secret'] = $accessToken['oauth_token_secret'];
  header('Location: '.$callbackUrl);
  exit;
} else
{
  $oauthClient->setToken($_SESSION['token'], $_SESSION['secret']);
  $resourceUrl = "$apiUrl/products";


  $productData = json_encode(array(
'type_id' => 'simple',
    'attribute_set_id' => 4,
    'sku' => $local_product['sku'],
    'weight' => 1,
    'status' => 1,
'visibility' => 4,
    'name' => $local_product['name'],
    'description' => $local_product['description'],
    'short_description' => $local_product['description'],
    'price' => $local_product['price'],
    'tax_class_id' => 0,
  ));
  $headers = array('Content-Type' => 'application/json');
  $oauthClient->fetch($resourceUrl, $productData, OAUTH_HTTP_METHOD_POST, $headers);
  $respHeader = $oauthClient->getLastResponseHeaders();


}

} catch(OAuthException $e)
{
  print_r($e);
}
}

session_destroy();

确切错误:{"messages":{"error":[{"code":401,"message":"oauth_problem=nonce_used"}]}}

【问题讨论】:

  • 在 Magento 中添加产品的实际调用似乎每进行 1 次调用就会运行两次。我在 ../Mage/Oauth/Model/Server.php 中编辑了 _validateNonce 函数以跳过验证过程,现在我收到一个错误,表明我要插入的产品中的 SKU 必须是唯一的(并且它正在插入产品)。所以它似乎是插入产品然后尝试再次插入导致错误......这应该很有趣......任何人都想打败我;-)
  • 您找到解决方案了吗?遇到同样的问题,绝对不可能破解核心代码。

标签: api magento rest oauth


【解决方案1】:

我遇到了完全相同的问题,为了解决它,我查看了 mod_rewrite apache 模块并打开了该模块的日志记录,这是通过将其添加到您的 apache httpd.conf 文件来完成的(这是针对 apache 2.4x 、 2.2x需要以不同的方式完成

<IfModule mod_rewrite.c>
   LogLevel mod_rewrite.c:trace8
</IfModule>

然后将错误记录到 apache 标准 error_log 当我查看这里的重写时,我可以看到我的 post 请求被重写了两次,第一次将产品添加到 magento 中,第二次由于使用了随机数而再次添加产品失败,显然。

我可以看到在 .htaccess 中导致这种情况的重写规则是一个

## workaround for HTTP authorization
## in CGI environment

  RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] 

我检查了我的配置,我确实在运行快速 cgi php,我通过检查 php 信息脚本中的服务器 API 的值来检查这一点。我花了很长时间试图解决这个问题,以至于我知道根本原因我只是将 PHP 从 CGI php 更改为 apache 模块,嘿,现在我的 post 请求只重写一次并返回所有难以捉摸的 200 响应代码。

【讨论】:

    【解决方案2】:

    我查看了这个,从我在代码中看到的内容来看,OAuth 似乎注册了您的所有调用,并且如果它发现完全相同的 nonce 实际上与完全相同的 一起使用>timestamp 作为之前的调用,它只会丢弃这个非常具体的 oauth_problem=nonce_used 错误。

    来自app/code/core/Mage/Oauth/Model/Server.php的代码

    /**
     * Validate nonce request data
     *
     * @param string $nonce Nonce string
     * @param string|int $timestamp UNIX Timestamp
     */
    protected function _validateNonce($nonce, $timestamp)
    {
        $timestamp = (int) $timestamp;
    
        if ($timestamp <= 0 || $timestamp > (time() + self::TIME_DEVIATION)) {
            $this->_throwException('', self::ERR_TIMESTAMP_REFUSED);
        }
        /** @var $nonceObj Mage_Oauth_Model_Nonce */
        $nonceObj = Mage::getModel('oauth/nonce');
    
        $nonceObj->load($nonce, 'nonce');
    
        if ($nonceObj->getTimestamp() == $timestamp) {
            $this->_throwException('', self::ERR_NONCE_USED);
        }
        $nonceObj->setNonce($nonce)
            ->setTimestamp($timestamp)
            ->save();
    }
    

    所以我想说,当您通过 REST 中的 Magento API 进行调用时,您应该格外小心,您发出的每个请求都有自己独特的生成的组合时间戳/nonce 值。

    另见

    oauth_nonce。由应用程序唯一生成的随机值。
    oauth_timestamp。一个正整数,以自 1970 年 1 月 1 日 00:00:00 GMT 以来的秒数表示。

    nonce_used:nonce-timestamp 组合已被使用。

    来自此来源:http://devdocs.magento.com/guides/v2.0/get-started/authentication/gs-authentication-oauth.html

    【讨论】:

      【解决方案3】:

      在 Mage_Api2_Model_Resource 中,大约第 227 行,定位

      $this->getResponse()->setHeader('Location', $newItemLocation);
      

      并在此之后插入:

       $this->getResponse()->setHttpResponseCode(202); 
      

      参考:维基百科“HTTP 位置”:

      HTTP Location 标头字段在来自 HTTP 的响应中返回 服务器分两种情况:

      1. 要求网络浏览器加载不同的网页。在这个 在这种情况下,Location 标头应与 HTTP 状态一起发送 代码 3xx。
      2. 提供有关新的位置的信息 创建的资源。在这种情况下,Location 标头应该 发送 HTTP 状态码 201 或 202

      【讨论】:

      • 这确实有效,但我们需要另一个不修改 Magento 核心文件的解决方案 @user1392439
      • 感谢您的评论。您也可以使用$this-&gt;getResponse(); 来执行此操作... setHttpResponseCode 不是必需的。
      【解决方案4】:

      我遇到了完全相同的问题,并花了数周时间追踪问题。这似乎是 Apache 与 PHP 和 Rewriting 的奇怪组合。最后我创建了一个干净的安装,问题就消失了。我还尝试创建可以观察到问题但失败的第二个安装 - 该错误仅出现在我的生产系统中,而不出现在任何测试安装中...

      【讨论】:

        【解决方案5】:

        解决方法:

        使用 SOAP API。

        之前没用过的原因:

        SOAP API 不提供自定义产品属性或产品数量增量字段的功能。

        修复:

        使用 SOAP api 将您想要的任何字段添加到产品中,方法是首先为它们创建一个对象数组,如下所示(下面的最后 4 行代码针对添加的每个字段重复):

        $additionalAttrs = array();
        
        $per_item = new stdClass();
        $per_item->key = 'price_per_item';
        $per_item->value = $local_product['price'];
        $additionalAttrs['single_data'][] = $per_item;
        

        然后使用“additional_attributes”键将其添加到您的产品数组中,例如:

        'additional_attributes' => $additionalAttrs,
        

        我知道这种解决方法只会帮助那些出于同样原因而避免使用 SOAP API 的人,但希望它对你们中的一些人有所帮助。我们看到它尝试添加产品两次的错误似乎是特定于服务器配置的,很难追踪。

        【讨论】:

          猜你喜欢
          • 2016-07-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-01-14
          • 1970-01-01
          • 2017-04-29
          相关资源
          最近更新 更多