当前位置: 首页 > 面试题库 >

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

宰宣
2023-03-14
问题内容

我正在尝试使用Python访问poloniex.com(一种加密货币交易所)上的交易API。为此,我必须遵循以下规定:

所有对交易API的调用都通过HTTP
POST发送到https://poloniex.com/tradingApi,并且必须包含以下标头:

密钥-您的API密钥。
签名-根据HMAC-SHA512方法,由您的键的“秘密”对查询的POST数据进行签名。

此外,所有查询都必须包含“ nonce” POST参数。随机数参数是一个整数,必须始终大于先前使用的随机数。

这是我到目前为止所拥有的。我当前的问题是,我不知道如何编译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)

问题答案:

创建 准备好的
请求
; 您可以在创建主体之后在其中添加标题:

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中发送。

对于随机数,我将使用从当前时间播种的itertools.count()object,因此重新启动不会影响它。根据Poloniex
API文档(在问题中引用的内容),随机数是POST主体的一部分,而不是标头,因此将其放在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())如果您每秒创建多个请求,则使用将重复使用相同的数字。在由Poloniex提供的示例代码的用途int(time.time()*1000),以使其能够创建请求每微秒,而不是,而是用自己的单调递增计数器(从种子time.time())是稳健得多。

您还可以将摘要签名过程封装在自定义身份验证对象中;在准备好的请求中传递这样的对象,作为准备的最后一步:

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摘要中使用的秘密。您还可以传入其他标题名称。



 类似资料:
  • 我向我的flask应用所在的服务器发出了python post请求。它运行良好,我能够获得所需的数据。 但我想用POSTMAN测试API。我无法做到这一点,因为在某种程度上我对邮递员并不熟悉。 下面是我的python代码。 我正在努力解决这样一个问题:我试图发布到服务器上的数据和文件应该是原始json还是表单数据,或者是正文的x-www-form-urlencoded部分。还有实际的结构应该是什么

  • 编辑:问题是我使用十六进制编码的字符串作为键,我应该使用原始字节。如何从openssl命令中获取原始字节? ---原问题--- 我正在尝试按照以下说明创建签名iam请求:https://docs.aws.amazon.com/general/latest/gr/sigv4-calculate-signature.html. 它基本上是说要产生签名密钥和签名,您需要遵循以下步骤: 我创建了以下外壳脚

  • httpx 怎么发一个 post http2 请求 curl --http2-prior-knowledge -X POST http://127.0.0.1:1313 -d 'ww$$go' 这个 curl 是有效的,但怎么使用 httpx 来实现

  • 本文向大家介绍python-requests POST请求,包括了python-requests POST请求的使用技巧和注意事项,需要的朋友参考一下 示例 POST请求是使用方法发出的。request.post() 如果您需要发送Web表单请求作为POST正文,请传入以键值对作为data参数的字典;requests会将它们编码为application/x-www-form-urlencoded模

  • 我正在使用POST请求向服务器发送CSV文件。 我正在使用一个类似文件的对象与 如果CSV文件相当大,并且我的内存有限,或者我使用类似文件的对象将永远不会在内存中加载整个文件,那么会有问题吗?我对此不确定。 我知道有流选项,但听起来更像是为了获得响应而不是发送数据。

  • 问题内容: 我不想使用文件,但是只有django才需要发出POST请求。 就像发送请求一样。 问题答案: 结合使用urllib2和urllib中的方法即可解决问题。这是我使用这两种方法发布数据的方式: 是用于打开URL的方法。 将参数转换为百分比编码的字符串。