有没有人有可以为 Walmart API 生成此标头的 python 代码?
WM_SEC.AUTH_SIGNATURE
我试图围绕 Java 示例进行思考,但我没有任何运气,因为我没有 Java 经验。
如果有人知道需要签名的字符串的格式,我可能会从那里弄清楚。
我该如何解决这个问题?
有没有人有可以为 Walmart API 生成此标头的 python 代码?
WM_SEC.AUTH_SIGNATURE
我试图围绕 Java 示例进行思考,但我没有任何运气,因为我没有 Java 经验。
如果有人知道需要签名的字符串的格式,我可能会从那里弄清楚。
我该如何解决这个问题?
如果有人需要,这是我最终用来获得授权工作的代码:
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)
下面是 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');
}
}
请注意,这种身份验证方法将不再适用。
我们将于 2019 年 8 月 28 日弃用基于数字签名的身份验证(消费者 ID 和私钥)。如果您当前正在使用此方法,那么您的 API 调用将在 2019 年 8 月 28 日之后不起作用。
但是,如果您仍然想尝试:
来自API 文档
要使用您自己的代码获取数字签名,请执行以下步骤:
- 发给您的消费者 ID_ + "\n" +
- 您正在进行的 API 调用的 URL + "\n" +
- 您在所有大写字母中进行的 API 调用的请求方法 + "\n" +
- 现在的 Unix 纪元时间戳(自 1970 年 1 月 1 日 UTC 以来的毫秒数)+ "\n"
** 注意:参数的顺序和行返回\n对于正确生成签名很重要
使用以下步骤生成步骤 3 中列出的结构化数据的字节数组:使用 Base-64 解码字节数组。
湾。使用 PKCS#8 对结果值进行编码以表示您的私钥。各种语言的库提供了识别私钥是 PKCS#8 格式而不是其他冲突格式(如 PKCS#1)的能力。C。使用您的私钥的这个字节表示,使用带有 RSA 的 SHA-256 对数据进行签名。d。使用 Base-64 对生成的数字签名进行编码。
使用生成的数字签名和时间戳进行 API 调用。