此请求的签名对于 Binance US 无效 API
Signature for this request is not valid error for Binance US API
我在连接到需要身份验证的 Binance API 端点时收到签名无效错误。在 link 之后有一个类似的查询,但我猜它是 Binance 特有的,而且这个问题是 Binance US 特有的。我尝试使用下面 link 中的方法,但它没有用。
Flutter binance api signature
以下是Python代码
import urllib.parse
import hashlib
import hmac
import base64
import requests
api_url = "https://api.binance.us"
# get binanceus signature
def get_binanceus_signature(data, secret):
postdata = urllib.parse.urlencode(data)
message = postdata.encode()
byte_key = bytes(secret, 'UTF-8')
mac = hmac.new(byte_key, message, hashlib.sha256).hexdigest()
return mac
# Attaches auth headers and returns results of a POST request
def binanceus_request(uri_path, data, api_key, api_sec):
headers = {}
headers['X-MBX-APIKEY'] = api_key
signature = get_binanceus_signature(data, api_sec)
params={**data, "signature": signature}
req = requests.get((api_url + uri_path), params=params, headers=headers)
return req.text
api_key = "vmPUZE6mv9SD5VNHk4HlWFsOr6aKE2zvsw0MuIgwCIPy6utIco14y7Ju91duEh8A"
secret_key = "NhqPtmdSJYdKjVHjA7PZj4Mge3R5YNiP1e3UZjInClVN65XAbvqqM6A7H5fATj0j"
uri_path = "/api/v3/openOrders"
data = {
"symbol": "BTCUSDT",
"timestamp": 1499827319559
}
get_open_order_result = binanceus_request(uri_path, data, api_key, secret_key)
这是完整的飞镖代码。
class BinanceUSRestClient {
final String timestamp = DateTime.now().millisecondsSinceEpoch.toString();
Future<http.Response> getResponse({
required String secret,
required String apiKey,
required String path,
Map<String, dynamic>? queryParams,
}) async {
//Header
Map<String, String> headers = {};
headers['X-MBX-APIKEY'] = apiKey;
//Params
Map<String, dynamic> params = {};
if (queryParams != null) {
params.addAll(queryParams);
}
params['signature'] = createSignature(secret, queryParams);
params['timestamp'] = timestamp;
final Uri uri = Uri.https('api.binance.us', path, params);
http.Response response = await http.get(
uri,
headers: headers,
);
return response;
}
String createSignature(String secret, Map<String, dynamic>? data) {
final String jsonString = jsonEncode(data);
final List<int> message = utf8.encode(jsonString);
final List<int> key = utf8.encode(secret);
final List<int> mac = Hmac(sha256, key).convert(message).bytes;
final String signature = hex.encode(mac);
return signature;
}
}
如果有帮助,请点击此处 API documentation。有人可以帮我解决这个错误吗?
终于!!花了几个小时后,shammy12's post 帮我弄清楚出了什么问题。一直以来,我一直在尝试根据 json 格式的参数创建签名。尽管 Binance US 文档中明确指出,
totalParams
is defined as the query string
concatenated with the
request body
我引用的大多数回复都忽略了这一点。即使 recvWindow
参数也与无效签名错误无关。我调试这个问题只需要找出一种将查询格式化为
的方法
String _paramsString = 'timestamp=' + timeStamp.toString();
并且,这是通过使用以下内容实现的:
String _paramsString = Uri(queryParameters: baseParams).query;
这是完整的调试代码。如果有任何问题,请随时告诉我。我重命名了一些变量以提高可读性并避免一些可能的混淆。
import 'dart:convert';
import 'package:convert/convert.dart';
import 'package:crypto/crypto.dart';
import 'package:http/http.dart' as http;
class BinanceRestClient {
final int timeStamp = DateTime.now().millisecondsSinceEpoch;
Future<http.Response> getResponse({
required String secret,
required String apiKey,
required String path,
Map<String, dynamic>? queryParams,
}) async {
//Header
Map<String, String> headers = {};
headers['X-MBX-APIKEY'] = apiKey;
//Base params include the timestamp in milliseconds since epoch
//and query parameters required for API end point
Map<String, dynamic> baseParams = {};
baseParams['timestamp'] = timeStamp.toString();
if (queryParams != null) {
baseParams.addAll(queryParams);
}
//Total params is the combination of base params and signature.
Map<String, dynamic> totalParams = baseParams;
totalParams['signature'] = _createSignature(
secret: secret,
baseParams: baseParams,
);
final Uri uri = Uri.https('api.binance.us', path, totalParams);
final http.Response response = await http.get(
uri,
headers: headers,
);
return response;
}
String _createSignature({
required String secret,
required Map<String, dynamic> baseParams,
}) {
//Important Note: baseParams must be changed to a concatenated string before hashed.
//Failure to do so will result in signature invalid error
//
//i.e., String _paramsString = 'timestamp=' + timeStamp.toString();
//
//Following converts a json query to a concatenated string
final String _paramsString = Uri(queryParameters: baseParams).query;
final List<int> _message = utf8.encode(_paramsString);
final List<int> _key = utf8.encode(secret);
final List<int> _mac = Hmac(sha256, _key).convert(_message).bytes;
final String _signature = hex.encode(_mac);
return _signature;
}
}
我在连接到需要身份验证的 Binance API 端点时收到签名无效错误。在 link 之后有一个类似的查询,但我猜它是 Binance 特有的,而且这个问题是 Binance US 特有的。我尝试使用下面 link 中的方法,但它没有用。
Flutter binance api signature
以下是Python代码
import urllib.parse
import hashlib
import hmac
import base64
import requests
api_url = "https://api.binance.us"
# get binanceus signature
def get_binanceus_signature(data, secret):
postdata = urllib.parse.urlencode(data)
message = postdata.encode()
byte_key = bytes(secret, 'UTF-8')
mac = hmac.new(byte_key, message, hashlib.sha256).hexdigest()
return mac
# Attaches auth headers and returns results of a POST request
def binanceus_request(uri_path, data, api_key, api_sec):
headers = {}
headers['X-MBX-APIKEY'] = api_key
signature = get_binanceus_signature(data, api_sec)
params={**data, "signature": signature}
req = requests.get((api_url + uri_path), params=params, headers=headers)
return req.text
api_key = "vmPUZE6mv9SD5VNHk4HlWFsOr6aKE2zvsw0MuIgwCIPy6utIco14y7Ju91duEh8A"
secret_key = "NhqPtmdSJYdKjVHjA7PZj4Mge3R5YNiP1e3UZjInClVN65XAbvqqM6A7H5fATj0j"
uri_path = "/api/v3/openOrders"
data = {
"symbol": "BTCUSDT",
"timestamp": 1499827319559
}
get_open_order_result = binanceus_request(uri_path, data, api_key, secret_key)
这是完整的飞镖代码。
class BinanceUSRestClient {
final String timestamp = DateTime.now().millisecondsSinceEpoch.toString();
Future<http.Response> getResponse({
required String secret,
required String apiKey,
required String path,
Map<String, dynamic>? queryParams,
}) async {
//Header
Map<String, String> headers = {};
headers['X-MBX-APIKEY'] = apiKey;
//Params
Map<String, dynamic> params = {};
if (queryParams != null) {
params.addAll(queryParams);
}
params['signature'] = createSignature(secret, queryParams);
params['timestamp'] = timestamp;
final Uri uri = Uri.https('api.binance.us', path, params);
http.Response response = await http.get(
uri,
headers: headers,
);
return response;
}
String createSignature(String secret, Map<String, dynamic>? data) {
final String jsonString = jsonEncode(data);
final List<int> message = utf8.encode(jsonString);
final List<int> key = utf8.encode(secret);
final List<int> mac = Hmac(sha256, key).convert(message).bytes;
final String signature = hex.encode(mac);
return signature;
}
}
如果有帮助,请点击此处 API documentation。有人可以帮我解决这个错误吗?
终于!!花了几个小时后,shammy12's post 帮我弄清楚出了什么问题。一直以来,我一直在尝试根据 json 格式的参数创建签名。尽管 Binance US 文档中明确指出,
totalParams
is defined as thequery string
concatenated with therequest body
我引用的大多数回复都忽略了这一点。即使 recvWindow
参数也与无效签名错误无关。我调试这个问题只需要找出一种将查询格式化为
String _paramsString = 'timestamp=' + timeStamp.toString();
并且,这是通过使用以下内容实现的:
String _paramsString = Uri(queryParameters: baseParams).query;
这是完整的调试代码。如果有任何问题,请随时告诉我。我重命名了一些变量以提高可读性并避免一些可能的混淆。
import 'dart:convert';
import 'package:convert/convert.dart';
import 'package:crypto/crypto.dart';
import 'package:http/http.dart' as http;
class BinanceRestClient {
final int timeStamp = DateTime.now().millisecondsSinceEpoch;
Future<http.Response> getResponse({
required String secret,
required String apiKey,
required String path,
Map<String, dynamic>? queryParams,
}) async {
//Header
Map<String, String> headers = {};
headers['X-MBX-APIKEY'] = apiKey;
//Base params include the timestamp in milliseconds since epoch
//and query parameters required for API end point
Map<String, dynamic> baseParams = {};
baseParams['timestamp'] = timeStamp.toString();
if (queryParams != null) {
baseParams.addAll(queryParams);
}
//Total params is the combination of base params and signature.
Map<String, dynamic> totalParams = baseParams;
totalParams['signature'] = _createSignature(
secret: secret,
baseParams: baseParams,
);
final Uri uri = Uri.https('api.binance.us', path, totalParams);
final http.Response response = await http.get(
uri,
headers: headers,
);
return response;
}
String _createSignature({
required String secret,
required Map<String, dynamic> baseParams,
}) {
//Important Note: baseParams must be changed to a concatenated string before hashed.
//Failure to do so will result in signature invalid error
//
//i.e., String _paramsString = 'timestamp=' + timeStamp.toString();
//
//Following converts a json query to a concatenated string
final String _paramsString = Uri(queryParameters: baseParams).query;
final List<int> _message = utf8.encode(_paramsString);
final List<int> _key = utf8.encode(secret);
final List<int> _mac = Hmac(sha256, _key).convert(_message).bytes;
final String _signature = hex.encode(_mac);
return _signature;
}
}