如何使用HMAC-SHA512和Python请求库签署POST请求?

2024-04-23 20:30:18 发布

您现在位置:Python中文网/ 问答频道 /正文

我正试图使用Python访问poloniex.com上的交易API,这是一个加密货币交易所。为此,我必须遵循以下处方:

All calls to the trading API are sent via HTTP POST to https://poloniex.com/tradingApi and must contain the following headers:

Key - Your API key.
Sign - The query's POST data signed by your key's "secret" according to the HMAC-SHA512 method.

Additionally, all queries must include a "nonce" POST parameter. The nonce parameter is an integer which must always be greater than the previous nonce used.

这是我目前所拥有的。我目前的问题是,我不知道如何编译POST url,以便在不首先发送不完整请求的情况下对其进行签名。这显然行不通。

import requests
import hmac
import hashlib
import time

headers = { 'nonce': '',
            'Key' : 'myKey',
            'Sign': '',}
payload = { 'command': 'returnCompleteBalances',
            'account': 'all'}
secret = 'mySecret'

headers['nonce'] = int(time.time())
response = requests.post( 'https://poloniex.com/tradingApi', params= payload, headers= headers )
headers['Sign'] = hmac.new( secret, response.url, hashlib.sha512)

Tags: thetohttpsimportcomapisecrettime
1条回答
网友
1楼 · 发布于 2024-04-23 20:30:18

创建一个prepared request;您可以在创建主体后向其添加标题:

import requests
import hmac
import hashlib


request = requests.Request(
    'POST', 'https://poloniex.com/tradingApi',
    data=payload, headers=headers)
prepped = request.prepare()
signature = hmac.new(secret, prepped.body, digestmod=hashlib.sha512)
prepped.headers['Sign'] = signature.hexdigest()

with requests.Session() as session:
    response = session.send(prepped)

我将您的params参数更改为data;对于POST请求,通常是在正文中发送参数,而不是在URL中发送参数。

对于nonce,我将使用一个^{} object,从当前时间开始播种,这样重新启动不会影响它。根据Poloniex API documentation(您在问题中引用了这一点),nonce是POST主体的一部分,而不是header,因此将其放入payload字典中:

from itertools import count
import time

# store as a global variable
NONCE_COUNTER = count(int(time.time() * 1000))

# then every time you create a request
payload['nonce'] = next(NONCE_COUNTER)

如果每秒创建多个请求,使用int(time.time())将重复使用相同的数字。example code provided by Poloniex使用int(time.time()*1000)来使每微秒创建一个请求成为可能,但是使用您自己的单调递增计数器(从time.time()种子)要健壮得多。

您还可以将摘要签名过程封装在custom authentication object中;这样的对象在准备好的请求中作为准备的最后一步传递:

import hmac
import hashlib

class BodyDigestSignature(object):
    def __init__(self, secret, header='Sign', algorithm=hashlib.sha512):
        self.secret = secret
        self.header = header
        self.algorithm = algorithm

    def __call__(self, request):
        body = request.body
        if not isinstance(body, bytes):   # Python 3
            body = body.encode('latin1')  # standard encoding for HTTP
        signature = hmac.new(self.secret, body, digestmod=self.algorithm)
        request.headers[self.header] = signature.hexdigest()
        return request

在您的requests调用中使用此选项:

response = requests.post(
    'https://poloniex.com/tradingApi',
    data=payload, headers=headers, auth=BodyDigestSignature(secret))

传入的参数是HMAC摘要中使用的机密;您还可以传入不同的头名称。

相关问题 更多 >