How to fit Binance API signature error msg - 1022? - rest

When I try to make a request I get the following error message:
code: -1022, Signature for this request is not valid
The request is being made to https://api.binance.com/sapi/v1/capital/address. There is no error when using the time stamp parameter. However, using the coin parameter or any other parameter will cause an error.
String path = '/sapi/v1/capital/deposit/address?';
String coin = 'coin=BTC';
int timeStamp = DateTime.now().millisecondsSinceEpoch;
String queryParams = '&recvWindow=60000' + '&timestamp=' + timeStamp.toString();
String secret = 'secret key';
List<int> messageBytes = utf8.encode(queryParams);
List<int> key = utf8.encode(secret);
Hmac hmac = new Hmac(sha256, key);
Digest digest = hmac.convert(messageBytes);
String signature = hex.encode(digest.bytes);
String url = baseUrl + path + queryParams + "&signature=" + signature;
void _fetchPosts() async {
final response = await http.get(url, headers: {
"Accept": "application/json",
"X-MBX-APIKEY":
"API-KEY"
});```

Related

Uploading files to sharepoint with RestSharp and their rest API is adding header and trailer lines to every file

I'm uploading to sharepoint using a c# client, and every file I Upload gets extra data included. A one line CSV file gets turned into a 7 line file that isn't usable. This is what my one line file upload turned into:
-----------AEE7A299-297A-41E0-B1CC-A72050FCDD28
Content-Disposition: form-data; name="ControlFile_RCTI_statement_20220218_145832.csv"; filename="ControlFile_RCTI_statement_20220218_145832.csv"
Content-Type: application/octet-stream
File;Class;Account Number;Effective Date;Product;Account Type;Document Name
-----------AEE7A299-297A-41E0-B1CC-A72050FCDD28--
My upload code is using restSharp
public async Task UploadFile(string filePath, string list, string folderPath)
{
await CheckTokenAsync();
var fileName = Path.GetFileName(filePath);
var endpoint = $"{spCredentials.sharepointSubSiteFullUrl}/_api/web/GetFolderByServerRelativeUrl('{list}/{folderPath}')/Files/Add(url='{fileName}', overwrite=false)";
var client = new RestClient(endpoint);
client.Timeout = 30000;
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", $"Bearer {token}");
request.AddHeader("Accept", "application/json;odata=verbose");
request.AddFile(fileName, filePath);
var response = await client.ExecuteAsync(request);
if (response.StatusCode == HttpStatusCode.OK)
{
var fileData = JsonConvert.DeserializeObject<SPSingleResultContainer>(response.Content);
var link = fileData.d.__metadata.uri;
await SendRequest<string>($"{link}/CheckIn()", Method.POST);
}
else
throw new Exception($"Upload Failed with message: " + response.ErrorMessage);
}
I've also added this question to the sharepoint SE at https://sharepoint.stackexchange.com/questions/300550/uploading-files-to-sharepoint-with-restsharp-and-their-rest-api-is-adding-header
Turned out RestSharp was doing a multipart upload, and sharepoint doesn't like that sort of thing. Other people have had This Issue with RestSharp
public async Task UploadFile(string filePath, string list, string folderPath)
{
var bytes = File.ReadAllBytes(filePath);
await UploadFileData(Path.GetFileName(filePath), list, folderPath, bytes);
return;
}
public async Task UploadFileData(string fileName, string list, string folderPath, byte[] fileData)
{
await CheckTokenAsync();
var endpoint = $"{spCredentials.sharepointSubSiteFullUrl}/_api/web/GetFolderByServerRelativeUrl('{list}/{folderPath}')/Files/Add(url='{fileName}', overwrite=false)";
var client = new RestClient(endpoint);
client.Timeout = 30000;
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", $"Bearer {token}");
request.AddHeader("Accept", "application/json;odata=verbose");
string contentType = "";
var fileType = Path.GetExtension(fileName).ToLower();
switch (fileType)//there are better ways to get the MIME type, I was just getting desperate and trying everything
{
case ".csv":
contentType = "text/csv";
break;
case ".xlsx":
contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
break;
case ".pdf":
contentType = "application/pdf";
break;
case ".html":
contentType = "text/html";
break;
default:
throw new NotImplementedException($"File type {fileType} not supported");
}
request.AddHeader("Content-Type", contentType);
request.AddParameter(contentType, fileData, ParameterType.RequestBody);
var response = await client.ExecuteAsync(request);
var test = JsonConvert.SerializeObject(request);
if (response.StatusCode == HttpStatusCode.OK)
{
var fileMetaData = JsonConvert.DeserializeObject<SPSingleResultContainer>(response.Content);
var link = fileMetaData.d.__metadata.uri;
await SendRequest<string>($"{link}/CheckIn()", Method.POST);
}
else
throw new Exception($"Upload {fileName} Failed with status {response.StatusCode} and message: " + response.ErrorMessage);
}
For anyone coming here that doesn't care about sharepoint, replacing .addfile with
request.AddHeader("Content-Type", contentType);
request.AddParameter(contentType, fileData, ParameterType.RequestBody);
where contentType is the MIME format of your file extension (or an empty string seems to work as well) solved the issue for me.

sign okex api in flutter

i have problem to sign api for okex
,in document of okex:
The OK-ACCESS-SIGN header is generated as follows:
Create a prehash string of timestamp + method + requestPath + body
(where + represents String concatenation). Prepare the SecretKey. Sign
the prehash string with the SecretKey using the HMAC SHA256. Encode
the signature in the Base64 format. Example:
sign=CryptoJS.enc.Base64.stringify(CryptoJS.HmacSHA256(timestamp +
'GET' + '/users/self/verify', SecretKey))
The timestamp value is the same as the OK-ACCESS-TIMESTAMP header with
millisecond format of ISO, e.g. 2020-12-08T09:08:57.715Z.
The request method should be in UPPERCASE: e.g. GET and POST.
The requestPath is the path of requesting an endpoint.
Example: /api/v5/account/balance
The body refers to the String of the request body. It can be omitted
if there is no request body (frequently the case for GET requests).
method i made fo sign is:
dynamic _getSign(String timestamp, String methodType, String url, String body) {
if (body.isEmpty) {
body = "";
}
String message = timestamp + methodType.toUpperCase() + url + body;
var hmacSha256 = Hmac(sha256, utf8.encode(oKSecretKey));
var mac = hmacSha256.convert(utf8.encode(message));
// var a = mac.bytes;
var a = base64Url.encode(mac.bytes);
print(a);
return a;
}
Future<String> getAccountInfo() async {
try {
String timestamp = getServerTime();
String url = '/api/v5/account/balance';
Response response = await OKEXApi.dio.get(url,
queryParameters: {},
options: Options(headers: {
"OK-ACCESS-KEY": oKACCESSKEY,
"OK-ACCESS-PASSPHRASE": oKACCESSPASSPHRASE,
"OK-ACCESS-TIMESTAMP": timestamp,
"OK-ACCESS-SIGN": _getSign(timestamp, "GET", url, ""),
'Accept': 'application/json',
'Content-type': 'application/json',
}));
print(response.data);
return response.data;
} on DioError catch (e) {
return e.error;
}
}
and for timestamp
String getServerTime() {
DateTime now = DateTime.now().toUtc();
String isoDate = now.toIso8601String();
return isoDate;
}
And when i send data, response is:
{"msg":"Invalid Sign","code":"50113"}
The spec says:
OK-ACCESS-TIMESTAMP header with millisecond format of ISO, e.g.
2020-12-08T09:08:57.715Z
Truncate the microseconds away like this:
final now = DateTime.now().toUtc();
final microlessNow = now.subtract(Duration(microseconds: now.microsecond));
final isoDate = microlessNow.toIso8601String();
print(isoDate);

Rest API call for delete entity returns 403 error

Following code is aimed at deleting a row from table with given partition key and rowkey. But I get following request/response in fiddler. How can I correct the error?
Request
DELETE https://hireazurestorageacct.table.core.windows.net/mytable(PartitionKey='sample1',%20RowKey='0001')?timeout=20 HTTP/1.1
Accept: application/json;odata=nometadata
x-ms-date: Mon, 08 May 2017 17:59:14 GMT
x-ms-version: 2015-04-05
Accept-Charset: UTF-8
MaxDataServiceVersion: 3.0;NetFx
DataServiceVersion: 1.0;NetFx
If-Match: *
Content-Type: application/json
Authorization: SharedKeyLite hireazurestorageacct:3ZHX8lYBec+/9ytiNQb+JV5dpFkLAieuwB5veMkLVUU=
Host: hireazurestorageacct.table.core.windows.net
Response
HTTP/1.1 403 Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
Content-Length: 299
Content-Type: application/json
Server: Microsoft-HTTPAPI/2.0
x-ms-request-id: a9244f7f-0002-0048-0824-c8afc5000000
Date: Mon, 08 May 2017 17:59:14 GMT
{"odata.error":{"code":"AuthenticationFailed","message":{"lang":"en-US","value":"Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.\nRequestId:a9244f7f-0002-0048-0824-c8afc5000000\nTime:2017-05-08T17:59:14.9335100Z"}}}
Code
public static int DeleteEntity(string storageAccount, string accessKey, string tableName, string partitionkey, string rowkey)
{
string uri = $#"https://{storageAccount}.table.core.windows.net/{tableName}(PartitionKey='{partitionkey}', RowKey='{rowkey}')?timeout=20";
string resource = $#"{tableName}";
// Web request
var request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = "DELETE";
request.Accept = "application/json;odata=nometadata";
request.Headers.Add("x-ms-date", DateTime.UtcNow.ToString("R", System.Globalization.CultureInfo.InvariantCulture));
request.Headers.Add("x-ms-version", "2015-04-05");
request.Headers.Add("Accept-Charset", "UTF-8");
request.Headers.Add("MaxDataServiceVersion", "3.0;NetFx");
request.Headers.Add("DataServiceVersion", "1.0;NetFx");
request.Headers.Add("If-Match", "*");
request.ContentType = "application/json";
// Signature string for Shared Key Lite Authentication must be in the form
// StringToSign = Date + "\n" + CanonicalizedResource
// Date
string stringToSign = request.Headers["x-ms-date"] + "\n";
// Canonicalized Resource in the format /{0}/{1} where 0 is name of the account and 1 is resources URI path
stringToSign += "/" + storageAccount + "/" + resource;
// Hash-based Message Authentication Code (HMAC) using SHA256 hash
var hasher = new HMACSHA256(Convert.FromBase64String(accessKey));
// Authorization header
string strAuthorization = "SharedKeyLite " + storageAccount + ":" + Convert.ToBase64String(hasher.ComputeHash(System.Text.Encoding.UTF8.GetBytes(stringToSign)));
// Add the Authorization header to the request
request.Headers.Add("Authorization", strAuthorization);
Thread.Sleep(1000);
// Execute the request
try
{
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
using (var r = new StreamReader(response.GetResponseStream()))
{
return (int)response.StatusCode;
}
}
}
catch (WebException ex)
{
// get the message from the exception response
using (var sr = new StreamReader(ex.Response.GetResponseStream()))
{
var res = sr.ReadToEnd();
// Log res if required
}
return (int)ex.Status;
}
}
Status 403 means you need to authenticate to access a resource. Any decent server will not give you anything that includes any information about the resource. So you will get the same reply, whether the resource is there or not.
According to your codes, I guess there are something wrong with your authorization token when you use the resource to generate the authorization token.
I suggest you could try below codes to delete the table entity.
Call method:
AzureTableHelper.DeleteEntity("{storageaccount}", "{accesskey}", "{tablename}", "{partitionkey}", "{rowkey}" );
Delete method:
public static int DeleteEntity(string storageAccount, string accessKey, string tableName, string partitionkey, string rowkey)
{
string host = string.Format(#"https://{0}.table.core.windows.net/", storageAccount);
string resource = string.Format(#"{0}", tableName) + string.Format("(PartitionKey='{0}',RowKey='{1}')", partitionkey, rowkey);
string uri = host + resource;
//if you want to check the etag you need firstly get the etag then delete the entity
//string jsonData = "";
//int responseCode = RequestResource(
// storageAccount,
// accessKey,
// resource,
// out jsonData);
//var jsonObject = JObject.Parse(jsonData);
//string time = jsonObject.GetValue("odata.etag").ToString();
//string time = obj.Timestamp;
// Web request
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri);
request.Method = "DELETE";
request.ContentType = "application/json";
request.Accept = "application/json;odata=nometadata";
request.Headers.Add("x-ms-date", DateTime.UtcNow.ToString("R", System.Globalization.CultureInfo.InvariantCulture));
request.Headers.Add("x-ms-version", "2015-04-05");
request.Headers.Add("If-Match", "*");
request.Headers.Add("Accept-Charset", "UTF-8");
request.Headers.Add("MaxDataServiceVersion", "3.0;NetFx");
request.Headers.Add("DataServiceVersion", "1.0;NetFx");
// Signature string for Shared Key Lite Authentication must be in the form
// StringToSign = Date + "\n" + CanonicalizedResource
// Date
string stringToSign = request.Headers["x-ms-date"] + "\n";
// Canonicalized Resource in the format /{0}/{1} where 0 is name of the account and 1 is resources URI path
stringToSign += "/" + storageAccount + "/" + resource;
// Hash-based Message Authentication Code (HMAC) using SHA256 hash
System.Security.Cryptography.HMACSHA256 hasher = new System.Security.Cryptography.HMACSHA256(Convert.FromBase64String(accessKey));
// Authorization header
string strAuthorization = "SharedKeyLite " + storageAccount + ":" + System.Convert.ToBase64String(hasher.ComputeHash(System.Text.Encoding.UTF8.GetBytes(stringToSign)));
// Add the Authorization header to the request
request.Headers.Add("Authorization", strAuthorization);
// Execute the request
try
{
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
using (System.IO.StreamReader r = new System.IO.StreamReader(response.GetResponseStream()))
{
string jsonResponse = r.ReadToEnd();
return (int)response.StatusCode;
}
}
}
catch (WebException ex)
{
// get the message from the exception response
using (System.IO.StreamReader sr = new System.IO.StreamReader(ex.Response.GetResponseStream()))
{
string res = sr.ReadToEnd();
// Log res if required
}
return (int)ex.Status;
}
}

Azure Storage Service throws 403 forbidden error when trying to call REST API to clear queue messages

I'm trying to clear all azure storage queue message via Queue Service REST API. I've verified that the code is correct, but it still returns a 403 forbidden error. The "StorageSharedKey" and "StorageAccountName" are correct since I'm able to connect to the azure queue using those values in the connection string for the azure queue client. The storage version I'm using is "2015-12-11".
Here is the code:
internal void ClearStorageQueueMessages(string queueName)
{
const string requestMethod = "DELETE";
string urlPath = $"{queueName}/messages";
var dateInRfc1123Format = DateTime.UtcNow.ToString("R", CultureInfo.InvariantCulture);
var canonicalizedHeaders = $"x-ms-date:{dateInRfc1123Format}\nx-ms-version:{StorageVersion}";
var canonicalizedResource = $"/{StorageAccountName}/{urlPath}";
var uri = new Uri($"https://{StorageAccountName}.queue.core.windows.net/{urlPath}");
var response = MakeDeleteRestCall(uri, requestMethod, dateInRfc1123Format, canonicalizedHeaders, canonicalizedResource);
}
internal RestResponse MakeDeleteRestCall(Uri uri, string requestMethod, string dateInRfc1123Format, string canonicalizedHeaders,
string canonicalizedResource)
{
var restResponse = new RestResponse();
var stringToSign = $"{requestMethod}\n\n\n\n\n\n\n\n\n\n\n\n{canonicalizedHeaders}\n{canonicalizedResource}";
var authorizationHeader = CreateAuthorizationHeader(stringToSign);
var request = (HttpWebRequest) WebRequest.Create(uri);
request.Method = requestMethod;
request.Headers.Add("x-ms-date", dateInRfc1123Format);
request.Headers.Add("x-ms-version", StorageVersion);
request.Headers.Add("Authorization", authorizationHeader);
//request.Accept = "application/atom+xml,application/xml";
request.Accept = "application/json";
//request.ContentType = "application/json";
using (var response = (HttpWebResponse) request.GetResponse())
{
restResponse.StatusCode = response.StatusCode;
var responseStream = response.GetResponseStream();
if (responseStream == null)
return restResponse;
using (var reader = new StreamReader(responseStream))
{
restResponse.ReturnedContent = reader.ReadToEnd();
}
}
return restResponse;
}
internal static string CreateAuthorizationHeader(string canonicalizedString)
{
string signature;
using (var hmacSha256 = new HMACSHA256(Convert.FromBase64String(StorageSharedKey)))
{
var dataToHmac = Encoding.UTF8.GetBytes(canonicalizedString);
signature = Convert.ToBase64String(hmacSha256.ComputeHash(dataToHmac));
}
var authorizationHeader = string.Format(CultureInfo.InvariantCulture, "{0} {1}:{2}", StorageSharedKey,
StorageAccountName, signature);
return authorizationHeader;
}
The problem seems to be with the header Authorization. Please check the format according to the documentation:
Authorization="[SharedKey|SharedKeyLite] :"
https://msdn.microsoft.com/en-us/library/azure/dd179428.aspx
Your function adds the shared key in plain text instead of the authorization scheme "SharedKey" or "SharedKeyLite".

Saving PDF with Devdefined's IConsumerRequest

I'm trying to save a PDF from QBO however I'm stuck on this bit:
How do i get the IConsumerRequest to return a stream instead of a string? ReadBody only seems to send string rather than binary data...
IConsumerRequest conReq = oSession.Request();
conReq = conReq.Get().WithRawContentType("application/pdf");
string outURL = base_url + "invoice-document/v2/" + realmId + "/" + customerInvoicesWithinDateRange[0].Id.Value;
conReq = conReq.ForUrl(outURL);
conReq = conReq.SignWithToken();
string serviceResponse = conReq.ReadBody();
Thanks
instead of conReeq.ReadBody(), you can do this:
conReq.ToWebResponse().GetResponseStream();
in fact, ReadBody() is simply an extension method on IConsumerRequest, defined as:
public static string ReadBody(this IConsumerRequest request)
{
HttpWebResponse response = request.ToWebResponse();
return response.ReadToEnd();
}