使用 Python 在 Postman 外部验证 API 请求

Authenticating API Request outside of Postman using Python

我正在使用一个 API 的投资组合管理软件,并且已经提供了一些关于如何通过 Postman 实施它的文档。结果通过 Postman 变得清晰,但是当我尝试通过 Python 复制脚本时,我无法进行身份验证。除了 Python 之外,我不精通任何其他语言,而且我不是 API 专家(尤其是在身份验证方面)。我希望有人能够查看这段代码,看看在创建唯一签名方面是否有任何不正确的地方。或者,如果有人有使用 python 请求结构创建 HMAC 签名的经验。

import requests
import uuid
import time
import hmac
import base64
import hashlib
import math

url = "url"

payload = "{\n\t\"firm\": \"XXXXXXXX\",\n\t\"id\": \"#######\",\n\t\"data\": {\n\t\t\"tracking_preference\": 2\n\t} \n}\n"

apikey = 'apikey'

uuid = str(uuid.uuid4())
ts = math.floor(time.time())
timestamp = str(ts)

signature = timestamp+uuid

#signature_bytes = signature.encode('UTF8')
#secret_bytes = base64.standard_b64decode(apikey)

signature_bytes = bytes(signature, 'UTF8')
secret_bytes = bytes(apikey, 'UTF8')

signature_hash = hmac.new(secret_bytes, signature_bytes, hashlib.sha256).digest()
hmac = base64.b64encode(signature_hash).decode()


headers = {
    'X-SL-UUID': uuid,
    'X-SL-Timestamp': timestamp,
    'X-SL-HMAC': hmac,
    'Content-Type': "application/json",
    'User-Agent': "PostmanRuntime/7.18.0",
    'Accept': "*/*",
    'Cache-Control': "no-cache",
    'Postman-Token': "unique token",
    'Host': "xxxxxx-xxx.smartleaf.com",
    'Accept-Encoding': "gzip, deflate",
    'Content-Length': "89",
    'Connection': "keep-alive",
    'cache-control': "no-cache"
    }

response = requests.request("POST", url, data=payload, headers=headers)

print(response.text)

任何带有 "XXX" 或“###”的信息都是我模糊处理过的信息。提前致谢!

这是使用JS在Postman上的预请求脚本:

var apikey = '##########';

var uuidlib = require('uuid');
var uuid = uuidlib.v4();

var timestamp = Math.floor(Date.now() / 1000).toString();

var hash = CryptoJS.HmacSHA256(timestamp.concat(uuid), apikey);

postman.setEnvironmentVariable('timestamp', timestamp);
postman.setEnvironmentVariable('uuid', uuid);
postman.setEnvironmentVariable('hmac', hash);

直接翻译 Javascript 代码会导致:

import hmac
import hashlib
import time
import uuid
import requests

apikey = b'##########'
url = 'https://xxxxxx-xxx.smartleaf.com/'
payload = {'firm': 'XXXXXXXX', 'id': '#######', 'data': {'tracking_preference': 2}}

reqid = str(uuid.uuid4())
reqts = str(int(time.time()))

key = hmac.new(apikey, f'{reqts}{reqid}'.encode('ascii'), hashlib.sha256).hexdigest()

headers = {
    'X-SL-UUID': reqid,
    'X-SL-Timestamp': reqts,
    'X-SL-HMAC': key,
}

response = requests.post(url, json=payload, headers=headers)

主要是你用 base64 而不是十六进制对摘要进行编码

显然我无法对此进行测试,但希望它是正确的