C# Coinigy V2 API上的授权问题
我一直在从事一个项目,我曾经使用Conigy的v1API,并且喜欢这个api。现在的问题是新的v2api,我一直在尝试使用带有hmac_sha256签名的私有API。我最初联系coinigy支持部门,但由于运气不佳,无法使其完全工作(他们确实提供了帮助,但从未解决过问题,这很奇怪)。我用C#构建了一个简单的测试项目,用他们的api文档执行一个私有调用 program.cs:C# Coinigy V2 API上的授权问题,c#,http,bitcoin,cryptocurrency,C#,Http,Bitcoin,Cryptocurrency,我一直在从事一个项目,我曾经使用Conigy的v1API,并且喜欢这个api。现在的问题是新的v2api,我一直在尝试使用带有hmac_sha256签名的私有API。我最初联系coinigy支持部门,但由于运气不佳,无法使其完全工作(他们确实提供了帮助,但从未解决过问题,这很奇怪)。我用C#构建了一个简单的测试项目,用他们的api文档执行一个私有调用 program.cs: using Newtonsoft.Json.Linq; using System; using System.Collec
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
namespace coinigy_example
{
class Program
{
static void Main(string[] args)
{
string api_key = "API_KEY";
string api_secret = "API_SECRET";
CoinigyApiPrivateCall call = new CoinigyApiPrivateCall(api_key, api_decret);
string data = call.HttpPostRequest("private/exchanges/" + "BINA" + "/markets/" + "BTC" + "/" + "LTC" + "/ticker", "", null, "GET");
string body = null;
call.xcoinApiCall("private/exchanges/" + "BINA" + "/markets/" + "BTC" + "/" + "LTC" + "/ticker", "", ref body);
try
{
JObject j = JObject.Parse(data);
TickerDataCoinigy tt = new TickerDataCoinigy();
tt.volume = (string)j["volume"];
tt.last = (string)j["last"];
tt.high = (string)j["high"];
tt.low = (string)j["low"];
tt.ask = (string)j["ask"];
tt.bid = (string)j["bid"];
Console.WriteLine("Binance, BTC-LTC ticker data:");
Console.WriteLine("Volume: " + tt.volume);
Console.WriteLine("Last: " + tt.last);
Console.WriteLine("High: " + tt.high);
Console.WriteLine("Low: " + tt.low);
Console.WriteLine("ask: " + tt.ask);
Console.WriteLine("bid: " + tt.bid);
}
catch(Exception i)
{
Console.WriteLine("");
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(data);
Console.ForegroundColor = ConsoleColor.White;
}
Console.ReadLine();
}
}
public class TickerDataCoinigy
{
public string volume;
public string last;
public string high;
public string low;
public string ask;
public string bid;
}
}
还有几个版本的私有调用(看看调用api的不同方式是否有效)
coinigyapiravatecall.cs
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
namespace coinigy_example
{
public class CoinigyApiPrivateCall
{
private string api_key;
private string api_secret;
public CoinigyApiPrivateCall(string api_key, string api_secret)
{
this.api_key = api_key;
this.api_secret = api_secret;
}
public static double ConvertToUnixTimestamp(DateTime date)
{
DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
TimeSpan diff = date.ToUniversalTime() - origin;
return Math.Floor(diff.TotalMilliseconds);
}
private string Hash_HMAC(string sKey, string sData)
{
byte[] rgbyKey = Encoding.ASCII.GetBytes(sKey);
using (var hmacsha256 = new HMACSHA256(rgbyKey))
{
byte[] inf = hmacsha256.ComputeHash(Encoding.ASCII.GetBytes(sData));
return (ByteToString(inf));
}
}
private string ByteToString(byte[] rgbyBuff)
{
string sHexStr = "";
for (int nCnt = 0; nCnt < rgbyBuff.Length; nCnt++)
{
sHexStr += rgbyBuff[nCnt].ToString("x2"); // Hex format
}
return (sHexStr);
}
private byte[] StringToByte(string sStr)
{
byte[] rgbyBuff = Encoding.ASCII.GetBytes(sStr);
return (rgbyBuff);
}
public string HttpPostRequest(string url, string au, List<KeyValuePair<string, string>> postdata, string httpType)
{
var client = new HttpClient();
//client.DefaultRequestHeaders.Add("User-Agent", ua);
//client.DefaultRequestHeaders.Add("X-API-KEY", api_key);
//client.DefaultRequestHeaders.Add("X-API-SECRET", api_secret);
string time = Convert.ToString(ConvertToUnixTimestamp(DateTime.Now.ToUniversalTime()));
FormUrlEncodedContent content = null;
string data = null;
if (postdata != null)
{
content = new FormUrlEncodedContent(postdata);
var output = Newtonsoft.Json.JsonConvert.SerializeObject(postdata);
data = api_key + time + httpType.ToUpper() + "/api/v2/" + url + output;
}
else
{
data = api_key + time + httpType.ToUpper() + "/api/v2/" + url;
}
string sign = Hash_HMAC(api_secret, data);
client.DefaultRequestHeaders.Add("X-API-SIGN", sign);
client.DefaultRequestHeaders.Add("X-API-TIMESTAMP", time);
HttpResponseMessage response = null;
if (httpType.ToUpper() == "POST")
{
response = client.PostAsync("https://api.coinigy.com/api/v2/" + url, content).Result;
}
if (httpType.ToUpper() == "GET")
{
response = client.GetAsync("https://api.coinigy.com/api/v2/" + url).Result;
}
if (httpType.ToUpper() == "PUT")
{
response = client.PutAsync("https://api.coinigy.com/api/v2/" + url, content).Result;
}
if (httpType.ToUpper() == "DELETE")
{
response = client.DeleteAsync("https://api.coinigy.com/api/v2/" + url).Result;
}
return response.IsSuccessStatusCode
? response.Content.ReadAsStringAsync().Result
: "ERROR:" + response.StatusCode + " " + response.ReasonPhrase + " | " + response.RequestMessage;
}
public JObject xcoinApiCall(string sEndPoint, string sParams, ref string sRespBodyData)
{
string sAPI_Sign = "";
string sPostData = sParams;
string sHMAC_Key = "";
string sHMAC_Data = "";
string sResult = "";
double nNonce = 0;
HttpStatusCode nCode = 0;
sPostData += "&endpoint=" + Uri.EscapeDataString(sEndPoint);
try
{
HttpWebRequest Request = (HttpWebRequest)WebRequest.Create("https://api.coinigy.com/api/v2/" + sEndPoint);
byte[] rgbyData = Encoding.ASCII.GetBytes(sPostData);
nNonce = ConvertToUnixTimestamp(DateTime.Now.ToUniversalTime());
sHMAC_Key = this.api_secret;
sHMAC_Data = api_key + nNonce.ToString() + "GET" + "/api/v2/" + sEndPoint;
//sHMAC_Data = sEndPoint + (char)0 + sPostData + (char)0 + nNonce.ToString();
sResult = Hash_HMAC(sHMAC_Key, sHMAC_Data);
//sAPI_Sign = Convert.ToBase64String(StringToByte(sResult));
sAPI_Sign = sResult;
Request.Headers.Add("X-API-SIGN", sAPI_Sign);
Request.Headers.Add("X-API-TIMESTAMP", nNonce.ToString());
Request.Method = "GET";
Request.ContentType = "application/x-www-form-urlencoded";
Request.UserAgent = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36";
/*Request.ContentLength = rgbyData.Length;
using (var stream = Request.GetRequestStream())
{
stream.Write(rgbyData, 0, rgbyData.Length);
} */
var Response = (HttpWebResponse)Request.GetResponse();
sRespBodyData = new StreamReader(Response.GetResponseStream()).ReadToEnd();
return (JObject.Parse(sRespBodyData));
}
catch (WebException webEx)
{
using (HttpWebResponse Response = (HttpWebResponse)webEx.Response)
{
nCode = Response.StatusCode;
using (StreamReader reader = new StreamReader(Response.GetResponseStream()))
{
sRespBodyData = reader.ReadToEnd();
try
{
return (JObject.Parse(sRespBodyData));
}
catch(Exception i)
{
}
}
}
}
return (null);
}
}
}
我正在使用以下代码执行http调用:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Coinigy_v2_api_2018.Functions;
using System.Net.Http;
namespace Coinigy_v2_api_test
{
class Program
{
static void Main(string[] args)
{
ApiRequest req = new ApiRequest();
req.BaseUrl = "https://api.coinigy.com";
req.Body = "";
req.Method = "GET";
req.Secret = "secret";
req.Key = "key";
req.Endpoint = "/api/v2/private/exchanges";
string signature = req.Signature;
HttpResponseMessage response = null;
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Add("X-API-SIGN", signature);
client.DefaultRequestHeaders.Add("X-API-TIMESTAMP", req.Timestamp);
response = client.GetAsync(req.BaseUrl + req.Endpoint).Result;
}
string r = null;
if (response.IsSuccessStatusCode)
{
r = response.Content.ReadAsStringAsync().Result;
}
Console.WriteLine(r);
Console.ReadLine();
}
}
}
再次提前感谢您 API文档可在此处找到: 2019-08-28:最新更新是端点在生成签名时必须要求查询参数未编码 首先要检查的是确保您使用的是v2api密钥/密码。旧的V1密钥不能与V2 api一起使用。如果升级订阅,则可能需要生成新密钥才能使其生效 下面是一个类,如果这不能解决问题,它应该会有所帮助:
public class ApiRequest
{
public string BaseUrl { get; set; }
public string Endpoint { get; set; }
public string Key { get; set; }
public string Secret { get; set; }
public string Method { get; set; }
public string Body { get; set; }
public string Timestamp { get; set; } = DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString();
/// <summary>
/// Each API request needs to be signed so the sender can be identified.
/// This property generates the signature based on the current request.
/// </summary>
public string Signature
{
get
{
var asciiEncoding = new ASCIIEncoding();
var hmac = new HMACSHA256(asciiEncoding.GetBytes(Secret));
string signature = Key + Timestamp + Method.ToUpper() + Endpoint + (Body ?? string.Empty);
byte[] signatureBytes = asciiEncoding.GetBytes(signature);
byte[] hashedSignatureBytes = hmac.ComputeHash(signatureBytes);
string hexSignature = string.Join(string.Empty, Array.ConvertAll(hashedSignatureBytes, hb => hb.ToString("X2")));
return hexSignature;
}
}
}
这里有一个额外的python3版本,它将执行整个过程:嘿,乔,谢谢你帮助我!不幸的是,我仍然有同样的问题,没有得到授权。我要添加一个编辑代码,我有,这是使用您的代码给我。我得到这个结果:{StatusCode:401,ReasonPhrase:'Unauthorized',Version:1.1,Content:System.Net.Http.StreamContent,Headers:{Date:Sun,2018年7月29日19:19:36 GMT Content Length:0}}@parkerbidGare您应该有3个头,但我只看到两个。我想你缺少的是X-API-KEY(不确定它的确切名称)@ParkerBidigare我在那里工作,这就是我知道它的原因。目前还没有很好的记录。我们将更新文档,使其更加完善clear@ParkerBidigare我已经对文档进行了更改,这些文档将很快发布到生产环境中。他们可能星期五到那里。如果你想在那之前解决细节问题,请随时在这里提问,或者在推特或电子邮件上联系我。我很高兴accessible@ParkerBidigare请查看最新更新。我认为这些信息是解决问题的关键
public class ApiRequest
{
public string BaseUrl { get; set; }
public string Endpoint { get; set; }
public string Key { get; set; }
public string Secret { get; set; }
public string Method { get; set; }
public string Body { get; set; }
public string Timestamp { get; set; } = DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString();
/// <summary>
/// Each API request needs to be signed so the sender can be identified.
/// This property generates the signature based on the current request.
/// </summary>
public string Signature
{
get
{
var asciiEncoding = new ASCIIEncoding();
var hmac = new HMACSHA256(asciiEncoding.GetBytes(Secret));
string signature = Key + Timestamp + Method.ToUpper() + Endpoint + (Body ?? string.Empty);
byte[] signatureBytes = asciiEncoding.GetBytes(signature);
byte[] hashedSignatureBytes = hmac.ComputeHash(signatureBytes);
string hexSignature = string.Join(string.Empty, Array.ConvertAll(hashedSignatureBytes, hb => hb.ToString("X2")));
return hexSignature;
}
}
}
BaseUrl : https://api.coinigy.com
Endpoint : /api/v2/private/exchanges?pythagoreanTheorem=a%5E2%2Bb%5E2%3Dc%5E2
Key : keykeykeykeykeykeykeykeykeykeyke
Secret : secretsecretsecretsecretsecretse
Method : GET
Timestamp : 1532718830 (which is 2018-07-27T19:13:50.6694555Z)
Body : (empty string)
Signature : B618C0B3C92632C701D7CEFC00AC9C8A0771989B21E00D61D4945F79239D2F87