Python调用Coinsbit私有API遇认证问题,求排查方案
Coinsbit私有API认证问题排查与解决方案
问题描述
我已成功调用Coinsbit公开API,但调用私有API时遇到认证错误。以下是我的代码:
import requests import json import time import hashlib import hmac import base64 def call_api(): api_key = 'API_KEY' api_secret = 'SECRET_KEY' request = '/api/v1/account/order_history' # /api/v1/order/new base_url = 'https://api.coinsbit.io/' data = { 'request': request, 'nonce': str(int(time.time())), } complete_url = base_url + request data_json_str = json.dumps(data, separators=(',', ':'), ensure_ascii=False) payload = base64.b64encode(data_json_str.encode('utf-8')).decode('utf-8') signature = hmac.new(api_secret.encode('utf-8'), payload.encode('utf-8'), hashlib.sha512).hexdigest() headers = { 'Content-type': 'application/json', 'X-TXC-APIKEY': api_key, 'X-TXC-PAYLOAD': payload, 'X-TXC-SIGNATURE': signature } try: res = requests.post(complete_url, headers=headers, data=data_json_str) res.raise_for_status() except requests.exceptions.RequestException as e: return {'error': str(e)} return {'result': res.json()} print(call_api())
已确认API密钥正确,怀疑签名生成或请求头设置有误,需要排查思路及Coinsbit私有API的特定要求。
排查思路
- 检查Nonce格式:Coinsbit要求nonce是递增的整数,不能重复且必须大于上一次请求的nonce。当前用秒级时间戳易重复,建议改用毫秒级时间戳
str(int(time.time()*1000))。 - 验证Payload生成流程:确保JSON序列化无多余空格,
separators=(',', ':')是正确的,但要确认data中的request值完全匹配API端点(路径前缀、大小写均需一致)。 - 签名算法校验:Coinsbit要求用HMAC-SHA512对Base64编码后的Payload签名,需确认:
- 签名时使用的是API Secret的原始字符串,无编码转换错误
- Payload是Base64编码后的JSON字符串,而非原始JSON
- 请求方法核对:部分私有API有明确请求方法要求,比如
order_history这类查询接口可能需要用GET而非POST。
Coinsbit私有API特定要求
- 必填请求头:
X-TXC-APIKEY:你的API密钥X-TXC-PAYLOAD:Base64编码后的请求参数JSON字符串(必须包含request和nonce)X-TXC-SIGNATURE:HMAC-SHA512签名结果(用API Secret对Payload签名后转十六进制)
- 参数规则:
- 所有私有请求必须携带
request(API端点完整路径)和nonce(递增整数) - JSON序列化必须紧凑(无空格),编码为UTF-8
- 所有私有请求必须携带
- 请求方法规范:查询类接口(如
order_history)用GET,操作类接口(如order/new)用POST,需严格遵循官方文档指定方法。
修正后的示例代码
import requests import json import time import hashlib import hmac import base64 def call_api(): api_key = 'API_KEY' api_secret = 'SECRET_KEY' endpoint = '/api/v1/account/order_history' base_url = 'https://api.coinsbit.io' # 用毫秒级nonce避免重复 nonce = str(int(time.time() * 1000)) data = { 'request': endpoint, 'nonce': nonce } # 紧凑序列化JSON并编码 data_json = json.dumps(data, separators=(',', ':'), ensure_ascii=False).encode('utf-8') payload = base64.b64encode(data_json).decode('utf-8') # 生成签名 signature = hmac.new(api_secret.encode('utf-8'), payload.encode('utf-8'), hashlib.sha512).hexdigest() headers = { 'X-TXC-APIKEY': api_key, 'X-TXC-PAYLOAD': payload, 'X-TXC-SIGNATURE': signature } try: # order_history为查询接口,使用GET方法 res = requests.get(f"{base_url}{endpoint}", headers=headers) res.raise_for_status() except requests.exceptions.RequestException as e: return {'error': str(e), 'response': res.text if 'res' in locals() else ''} return {'result': res.json()} print(call_api())
内容的提问来源于stack exchange,提问作者Carlos Ribeiro
相关产品推荐
相关产品推荐

