使用BitMEX API调用钱包接口添加参数时遭遇签名无效401错误
问题原因及解决方案
你的问题出在签名生成的内容与实际请求不匹配:签名里包含了带currency=DOGE参数的路径,但实际发送的请求并没有携带该参数,导致BitMEX验证签名时发现路径不一致,返回Signature not valid错误。此外,BitMEX要求GET请求的查询参数必须按key的ASCII升序排列后再参与签名生成。
修正后的代码
方式一:直接拼接带参数的URL
import requests import time import hashlib import hmac from urllib.parse import urlencode def get_assets(API_KEY, API_SECRET): base_url = 'https://www.bitmex.com' path = '/api/v1/user/wallet' # 定义查询参数,单参数时无需额外排序 params = {'currency': 'DOGE'} query_string = urlencode(params) # 构造用于签名的完整路径(含参数) signed_path = f"{path}?{query_string}" if query_string else path # 实际请求的完整URL url = f"{base_url}{signed_path}" expires = int(time.time()) + 5 verb = 'GET' body = '' # GET请求body为空 # 签名消息格式:请求方法 + 带参数的路径 + 过期时间 + 请求体 message = verb + signed_path + str(expires) + body signature = hmac.new( API_SECRET.encode('utf-8'), # 密钥需转为字节类型 message.encode('utf-8'), digestmod=hashlib.sha256 ).hexdigest() headers = { 'api-key': API_KEY, 'api-signature': signature, 'api-expires': str(expires), } response = requests.get(url, headers=headers) if response.status_code == 200: return response.json() else: return f"Error: {response.status_code} - {response.text}" # 替换为你的API密钥后调用 get_assets(API_KEY, API_SECRET)
方式二:使用requests的params参数传递
import requests import time import hashlib import hmac from urllib.parse import urlencode def get_assets(API_KEY, API_SECRET): base_url = 'https://www.bitmex.com' path = '/api/v1/user/wallet' params = {'currency': 'DOGE'} # 按key的ASCII顺序排序参数,确保签名与实际请求参数顺序一致 sorted_params = sorted(params.items()) query_string = urlencode(sorted_params) signed_path = f"{path}?{query_string}" if query_string else path expires = int(time.time()) + 5 verb = 'GET' body = '' message = verb + signed_path + str(expires) + body signature = hmac.new( API_SECRET.encode('utf-8'), message.encode('utf-8'), digestmod=hashlib.sha256 ).hexdigest() headers = { 'api-key': API_KEY, 'api-signature': signature, 'api-expires': str(expires), } # 用params传递参数,requests会自动按key排序,与签名用的参数顺序一致 response = requests.get(base_url + path, headers=headers, params=params) if response.status_code == 200: return response.json() else: return f"Error: {response.status_code} - {response.text}"
关键注意点
- 签名路径必须与实际请求一致:签名生成时的路径要包含完整的查询参数,不能出现“签名里带参数,请求里不带”的情况。
- 参数排序要求:BitMEX要求GET参数按key的ASCII升序排列后参与签名,多参数时必须严格遵守,否则签名会失效。
- 密钥转字节:
API_SECRET需要转为字节类型传入hmac.new,避免因字符串编码问题导致签名错误。
内容的提问来源于stack exchange,提问作者kian233
相关产品推荐
相关产品推荐

