【问题标题】:How to generate WM_SEC.AUTH_SIGNATURE?如何生成 WM_SEC.AUTH_SIGNATURE?
【发布时间】:2019-12-14 11:18:28
【问题描述】:

有没有人有可以为沃尔玛 API 生成这个标头的 python 代码?

WM_SEC.AUTH_SIGNATURE

我试图围绕 Java 示例进行思考,但我没有任何运气,因为我没有 Java 经验。

如果有人知道需要签名的字符串的格式,我可能会从那里弄清楚。

我该如何解决这个问题?

【问题讨论】:

  • 我知道已经晚了,但我认为 API 已死且不受支持。

标签: python walmart-api


【解决方案1】:

这是我最终用来获得授权以在有人需要时工作的代码:

import requests, json, pprint, time
from requests.auth import HTTPBasicAuth
import errno
from Crypto.Hash import SHA256
from Crypto.PublicKey import RSA
from Crypto.Signature import PKCS1_v1_5
import hashlib
import base64


ACCOUNT_SID = 'xxxxxx'
AUTH_TOKEN = 'xxxxxxxx'
BASE_URL = 'https://products.api.impactradius.com/Mediapartners/{}/'.format(ACCOUNT_SID)
API_PATH = 'Catalogs/4277'
consumerId = 'xxxxxxxx'
epoxTime = str(int(time.time()*1000))
keyVersion = '1'

URL = 'https://developer.api.walmart.com/api-proxy/service/affil/product/v2/items'


hashDict = { 'WM_CONSUMER.ID' : consumerId,
            'WM_CONSUMER.INTIMESTAMP' : epoxTime,
            'WM_SEC.KEY_VERSION' : keyVersion
            }
sortedHashString = hashDict['WM_CONSUMER.ID'] +'\n'+ hashDict['WM_CONSUMER.INTIMESTAMP'] +'\n'+ hashDict['WM_SEC.KEY_VERSION']+'\n'
encodedHashString = sortedHashString.encode()

try:
    with open('./WM_IO_private_key.pem', 'r') as f:
        key = RSA.importKey(f.read())
except IOError as e:
    print(e)

hasher = SHA256.new(encodedHashString)
signer = PKCS1_v1_5.new(key)
signature = signer.sign(hasher)

signature_enc = str(base64.b64encode(signature),'utf-8')

headers = { 'WM_CONSUMER.ID' : consumerId,
            'WM_CONSUMER.INTIMESTAMP' : epoxTime,
            'WM_SEC.AUTH_SIGNATURE' : signature_enc,
            'WM_SEC.KEY_VERSION' : keyVersion,
            'WM_QOS.CORRELATION_ID' : 'afjksldkfj4r8ojfns',
            'WM_IFX.CLIENT_TYPE' : 'INTERNAL',
            'WM_PREVIEW' : 'false',
            'WM_SHOW_REASON_CODES' : 'ALL',
            'Content-Type' : 'application/json',
            }

params = {
            'category' : '4171_1228385',
            'publisherId' : 'xxxxxxxxxxx'
        }

response = requests.get(URL, headers=headers, params=params)

jsonData = json.loads(response.text)

【讨论】:

    【解决方案2】:

    下面是 PHP 上的 Affiliates API 示例

    符号字符串(消息)

    $message = self::WM_CONSUMER_ID . "\n" . $milliseconds . "\n" . self::WM_SEC_KEY_VERSION . "\n";
    

    PHP 示例类

    <?php
    
    declare(strict_types=1);
    
    namespace WalmartBundle\Services;
    
    
    use phpseclib\Crypt\RSA;
    
    /**
     * Class WalmartAuthSignature
     *
     *  Thanks: https://github.com/fillup/walmart-auth-signature-php/blob/develop/src/Signature.php
     *
     * @package WalmartBundle\Services
     */
    class WalmartAuthSignature
    {
        public static function sign(string $message, string $privateKey): string
        {
            $rsa = new RSA();
    
            $decodedPrivateKey = base64_decode($privateKey);
            $rsa->setPrivateKeyFormat(RSA::PRIVATE_FORMAT_PKCS8);
            $rsa->setPublicKeyFormat(RSA::PRIVATE_FORMAT_PKCS8);
    
            if ($rsa->loadKey($decodedPrivateKey, RSA::PRIVATE_FORMAT_PKCS8)) {
                $rsa->setHash('sha256');
                $rsa->setSignatureMode(RSA::SIGNATURE_PKCS1);
                $signed = $rsa->sign($message);
    
                return base64_encode($signed);
            }
    
            throw new \Exception('Unable to load private key');
        }
    }
    

    【讨论】:

      【解决方案3】:

      请注意,这种身份验证方法将不再有效。

      我们将弃用基于数字签名的身份验证(Consumer ID 和私钥)于 2019 年 8 月 28 日。如果您目前正在使用此 方法,您的 API 调用将在 2019 年 8 月 28 日之后不起作用。

      但如果你还想试试:

      来自API documentation

      要使用您自己的代码获取数字签名,请按以下步骤操作:

      1. 获取您在卖家中心生成的消费者 ID 和 Base 64 编码的私钥。
      2. 获取您要调用的完整 URL,包括任何路径和查询参数。
      3. 使用 GET 方法构造数字签名的输入。
      4. 使用下面列出的结构:
      • 发给您的消费者 ID_ + "\n" +
      • 您正在进行的 API 调用的 URL + "\n" +
      • 您正在发出的 API 调用的请求方法,全部大写 + "\n" +
      • 现在的 Unix 纪元时间戳(自 1970 年 1 月 1 日 UTC 以来的毫秒数)+“\n”

      ** 注意:参数的顺序和返回的行\n对于正确生成签名很重要

      1. 使用以下步骤生成步骤 3 中列出的结构化数据的字节数组: 一种。使用 Base-64 解码字节数组。

        b.使用 PKCS#8 对结果值进行编码以表示您的私钥。 各种语言的库提供了识别私钥是 PKCS#8 格式而不是其他冲突格式(如 PKCS#1)的能力。 C。使用您的私钥的这个字节表示,使用带有 RSA 的 SHA-256 对数据进行签名。 d。使用 Base-64 对生成的数字签名进行编码。

      2. 使用生成的数字签名和时间戳进行 API 调用。

      【讨论】:

      • 谢谢。我实际上是在尝试将它用于 Affiliates API。这帮助我看到我需要在最终参数中添加一个“\n”。我现在能够成功调用附属 API。附属 API 是否也在 8 月 28 日弃用基于数字签名的身份验证?
      • 我无法以某种方式找到任何信息。
      • 这里也一样。似乎 Affiliates API 是一个被遗忘的资源。那里的小文档似乎有很多漏洞。
      • 好吧,这里也一样。 Affiliates API 文档在任何地方都没有提到这一点。嘿@plugcity 我可以问你一个简单的问题,你在代码中使用的“WM_SEC.KEY_VERSION”的值是多少?
      • 这是否仍在使用 Affiliates API?我看到这种方法在 Marketplace API 中已被弃用,但似乎找不到任何关于附属公司的信息。 (developer.walmart.com/#/apicenter/marketPlace/…)
      猜你喜欢
      • 2020-09-28
      • 1970-01-01
      • 2012-06-19
      • 2022-10-19
      • 2011-10-18
      • 2011-06-04
      • 2019-04-14
      • 2011-02-21
      • 1970-01-01
      相关资源
      最近更新 更多