发布数据时签名无效的问题
问题出在我尝试用aiohttp发送一个POST请求到某个交易所的API上。在这个请求中,我需要发送一些头信息:
headers = {
'X-Timestamp': str(timestamp),
'X-Window': str(self.WINDOW),
'X-API-Key': self.public_key,
'X-Signature': signature
}
所有的头信息都是正确的(我测试过),除了签名。
如果签名是以签名格式发送的,我总是会收到“无效签名”的错误。
它的结构应该是这样的:
instruction=orderExecute&postOnly=False&price=1&quantity=10&selfTradePrevention=Allow&side=Bid&symbol=SOL_USDC&timeInForce=IOC×tamp=1710451343478&window=6000
这是我尝试发送的POST请求
而且这个请求必须用私钥进行签名,私钥是和头信息中的公钥配对的,只有这样我才能发送带有一些参数的数据。
!!!“无效签名”!!!
请求体中的“参数”是正确的(更改它们会得到不同的响应)
“头信息”也是正确的,和请求体中的“参数”有同样的原因
关于签名结构的API文档: https://docs.backpack.exchange/#section/Authentication
这是我的代码
class Site:
WINDOW = 6000
def __init__(self, token, private_key):
self.public_key = token
self.private_key = private_key
async def headers(self, params: dict, instruction: str) -> dict:
timestamp = await self._unix_time()
params["window"] = self.WINDOW
params["timestamp"] = timestamp
sorted_params = sorted(params.items())
query_string = f"instruction={instruction}&"+'&'.join(f"{key}={value}" for key, value in sorted_params)
signature = await self._sign(query_string)
headers = {
'X-Timestamp': str(timestamp),
'X-Window': str(self.WINDOW),
'X-API-Key': self.public_key,
'X-Signature': signature
}
return headers
async def _sign(self, data):
private_key_bytes = base64.b64decode(self.private_key)
private_key = Ed25519PrivateKey.from_private_bytes(private_key_bytes)
signature = private_key.sign(data.encode())
signature_base64 = base64.b64encode(signature).decode()
return signature_base64
@staticmethod
async def _unix_time():
async with aiohttp.ClientSession() as session:
async with session.get("https://api.backpack.exchange/api/v1/time") as response:
return await response.text()
class Trade(Site):
def __init__(self, public_key, private_key):
super().__init__(public_key, private_key)
async def buy_order(self):
params = {
"orderType": OrderType.LIMIT.value,
"postOnly": PostOnly.FALSE.value,
"price": "1",
"quantity": "10",
"selfTradePrevention": SelfTradePrevention.ALLOW.value,
"side": Side.BUY.value,
"symbol": Symbol.SOL.value,
"timeInForce": TimeInForce.IOC.value,
}
headers = await self.headers(params=params, instruction=Instruction.ORDER_EXECUTE.value)
headers['Content-Type'] = 'application/json; charset=utf-8'
body = json.dumps(params)
r = await _handle_post(headers=headers, body=body)
1 个回答
0
这段历史的重点是,这个API非常新(而且不好用)。
当它接受带有这些参数的请求时:
params = {
"orderType": OrderType.LIMIT.value,
"postOnly": PostOnly.FALSE.value,
"price": "1",
"quantity": "10",
"selfTradePrevention": SelfTradePrevention.ALLOW.value,
"side": Side.BUY.value,
"symbol": Symbol.SOL.value,
"timeInForce": TimeInForce.IOC.value,
}
如果你尝试删除一些数据,你会收到一个提示,告诉你请求的内容有问题。
而如果没有问题,它会说签名有问题(其实不是)。
参数“postOnly”(无论是True还是False都一样)和其他东西发生了冲突,这才是导致签名问题的原因。