I'm trying to work out an api request for bittrex (account, not public) via ajax. Kicking back mention of Invalid Signature. I've already worked though the nonce, cors proxy and sha512 implementation. I seem to be missing something over here. Never had issues with ajax request, but haven't worked much with added encryption either.
Here are my setup variables & my request, followed by the error response.
Setup (w/ keys removed):
var apikey = 'removed12345';
var apisecret = 'removed12345';
var nonce = Math.floor(Date.now() /1000);
var proxy = 'https://cors-anywhere.herokuapp.com/';
var uri = proxy + 'https://bittrex.com/api/v1.1/account/getbalances?apikey='+apikey+'&nonce='+nonce;
var sign = CryptoJS.SHA512(uri, apisecret).toString();
Request:
$.ajax({
url: uri,
headers: {'apisign': sign},
type: "GET",
crossDomain: true,
dataType: "json",
success: function(bittrex) {
console.log(bittrex);
},
error: function(xhr, status) {
console.log("error");
console.log(status);
}
});
Response:
{success: false, message: "INVALID_SIGNATURE", result: null}
Related
My question is very simple and I thought creating this program would only take a couple hours. However now I have been working on it all day trying to figure out what I could be doing wrong.
All I am trying to do is post messages to slack using their postMessage api. I have been able to send messages succesfully using slacks testing methods.
This is the url that is outputted by the test
https://slack.com/api/chat.postMessage?token=xoxp-xxxxxx-xxxxxxxx-xxxxxxxx-xxxxxxxxxxx&channel=XXXXXXXX&text=Just%20need%20the%20url&as_user=jheuman&pretty=1
I then decided to try it out locally using this html file served from my file system
<!DOCTYPE html>
<html>
<head>
<title>Testing Slack API</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<button onClick="test()">Test</button>
<button onClick="test2()">Authorization Test</button>
<script>
function test() {
var apiUrl = "https://slack.com/api/chat.postMessage";
var token = "xoxp-xxxxx...";//my token has been omitted for security;
var channel = "#general";
var text = "Testing slack api";
var user = "jheuman";
var actualToken = "Bearer " + token;
$.ajax({
headers: {
'Authorization':actualToken,
'Content-Type':'application/json'
},
data: JSON.stringify({
"channel": channel,
"text": text,
"as_user": user
}),
dataType: 'json',
processData: false,
type: 'POST',
url: apiUrl
})
.done(function(data) {
console.log(JSON.stringify(data));
})
.fail(function(response) {
console.log(JSON.stringify(response));
});
};
function test2() {
var apiUrl = "https://slack.com/api/auth.test";
var token = "xoxp-xxxxx..."; //my token has been omitted for security
var channel = "#general";
var text = "Testing slack api";
var user = "jheuman";
var actualToken = "Bearer" + token;
$.ajax({
headers: {
'Authorization':actualToken
},
type: 'POST',
url: apiUrl,
})
.done(function(data) {
console.log(JSON.stringify(data));
})
.fail(function(response) {
console.log(JSON.stringify(response));
});
};
</script>
But when I click either button I get the following error:
Failed to load https://slack.com/api/chat.postMessage: Request header field
Authorization is not allowed by Access-Control-Allow-Headers in preflight
response.
So per a friends Suggestion I tried it out on a server. I used Web Server For Chrome to serve it up on port 8887. First without setting cors headers and then with setting cors headers. Both to no avail. I received the same error.
As you can see I also tried the auth.test call but I receive the same error.
Slack specifically states that they prefer an authorization header and that the api can handle json data.
Other things I have tried:
Having no header field with token in data:
data: JSON.stringify({
'token':actualToken,
'channel': channel,
'text': text,
'as_user': user
}),
dataType: 'json',
processData: false,
type: 'POST',
url: apiUrl
Errors received:
{"ok":false,"error":"invalid_form_data"}
Having no header field with token in data without 'Bearer':
data: JSON.stringify({
'token':token,
'channel': channel,
'text': text,
'as_user': user
}),
dataType: 'json',
processData: false,
type: 'POST',
url: apiUrl
Errors received:
{"ok":false,"error":"invalid_form_data"}
Things I have looked into but don't think will effect outcome
The type of token
So how do I get this post request to work?
I am not set on jquery or ajax, it is just what I have used in the past so if you have a different request library to use I'm all ears.
If you need more information I will try to give it to you
Since configuring CORS correctly for sending data with content-type application/json can be tricky, I would suggest to send the request as application/x-www-form-urlencoded which is the default for AJAX.
Example:
var apiUrl = "https://slack.com/api/chat.postMessage";
var token = MY_TOKEN;
var channel = "general";
var text = "Testing slack api";
var user = "jheuman";
$.ajax({
data: {
"token": token,
"channel": channel,
"text": text,
"as_user": user
},
dataType: 'text',
type: 'POST',
url: apiUrl,
error: function(xhr,status,error){
console.log("error: " + error);
},
success: function(data) {
console.log("result: " + data);
}
});
In case you get CORS errors, you can add crossDomain: true
This solution is tested and works when run in a normal browser.
You need to reply to that CORS preflight with the appropriate CORS headers to make this work. One of which is indeed Access-Control-Allow-Headers. That header needs to contain the same values the Access-Control-Request-Headers header contained (or more).
https://fetch.spec.whatwg.org/#http-cors-protocol explains this setup in more detail.
headers: {
'Authorization':actualToken,
'Content-Type':'application/json',
'Access-Control-Allow-Headers':'x-requested-with'
},
I am trying to send some data to a Flask app using json. When I send it I get a GET error in the console
GET http://super.secret.url/csv?callback=jQuery...
Javascript:
$.ajax({
type: 'POST',
contentType: "application/json; charset=utf-8",
url: "http://super.secret.url/csv?callback=?",
data: JSON.stringify({message: id, condition: "new"}),
dataType: "json"
});
Flask (python):
#app.route('/csv', methods=['POST'])
#crossdomain(origin='*')
def edit_csv(path):
ip = request.remote_addr
sessionId = request.json['message']
type = request.json['condition']
csvFile = csv.reader(open('ip_log.csv'))
csvLines = [l for l in csvFile]
if(type == "new"):
for i in range(0, len(csvLines)):
if(csvLines[i][0] == ip):
csvLines[i][1] == sessionId
break
csvwriter = csv.writer(open('ip_log.csv', 'w'))
csvwriter.writerows(csvLines)
return ""
Edit
I am getting a 405. I know this is a cross domain request but I do have the server setup to handle that. I have a different function in the python file that works cross domain.
To solve the cross domain problem, you may try JSONP instead of JSON.
For instance, the ajax code gives as follows:
$.ajax({
type: 'POST',
dataType: 'jsonp'
url: "http://super.secret.url/csv?callback=?",
jsonp: 'callback'//to get your own callback function name
jsonpCallback:'youOwnFunction',//'youOwnFunction' is callback function
//success or error function
});
return data shows like that
youOwnFunction({
//return data
});
While calling the api from JavaScript
This HTTP request works fine https://api.pcloud.com/userinfo?username=xxxx#gmail.com&password=xxxx
In the below code I want to call via JavaScript
var user='email loggin';
var password='password of pcloud';
function make_base_auth(user, password) {
var tok = user + ':' + password;
var hash = btoa(tok);
return "Basic " + hash;
}
$.ajax
({
type: "GET",
url: "https://api.pcloud.com/userinfo",
dataType: 'json',
async: false,
data: '{}',
beforeSend: function (xhr){
xhr.setRequestHeader('Authorization', make_base_auth(username, password));
},
success: function (){
alert('Working Fine');
}
});
output in console
XMLHttpRequest cannot load https://api.pcloud.com/userinfo?{}. Request header field Authorization is not allowed by Access-Control-Allow-Headers in preflight response.
If someone can provide a solution or enhance the code.
Pass the username and password in the data field and remove the "beforeSend" part. For more information and examples, you can check out the pCloud Javascript SDK: https://github.com/pCloud/pcloud-sdk-js
Here is working example (a bit shorter):
$.getJSON("https://api.pcloud.com/userinfo", {
username: "***",
password: "***"
}, function() {
alert("working fine");
});
I'm trying to write a plugin for TFS 2015 (its important). I read a couple of manuals. the examples all turns out simply, but it is more difficult with a real plugin. my problem: i cant send any get/post request from my tfs server to same server. I always get the same response: 401 Unauthorized. I looked at examples that sending Ajax requests (https://github.com/ALM-Rangers/Work-Item-Details-Widget-Extension/blob/master/src/scripts/menu.js) and add auth token to request, but i get same error 401.
my code:
VSS.require(["VSS/Authentication/Services"], function(Services) {
var authTokenManager = Services.authTokenManager;
VSS.getAccessToken().then(function(token) {
var header = authTokenManager.getAuthorizationHeader(token);
$.ajaxSetup({
headers: { 'Authorization': header }
});
$.ajax({
url: "http://myTFSServ:8080/tfs/_api/_common/GetCollectionJumpList?__v=5&navigationContextPackage=%7B%22Action%22%3A%22index%22%2C%22Area%22%3A%22%22%2C%22Level%22%3A8%2C%22Controller%22%3A%22workItems%22%7D&selectedHostId=6e60eeec-39b3-4902-a864-172cd27dea91&api-version=3.0-preview.2",
type: "GET",
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function(c) {
debugger;
// do something...;
},
error: function(e) {
debugger;
var error = e;
}
});
});
});
how can i send any valid get/post request from my tfs server to same server??
to get SharePoint List dataI am having an issue accessing the REST server via the CSOM. I have tried this with both the CSOM and just using jQuery. Code examples and the associated errors below. Can anyone direct me to a working example or tell me what I am doing wrong?
This code is part of a SharePoint Hosted App and the list is just a list in the root web. The user has permission to access the list and the app.
CSOM Example:
Yields:
Fail! : App Web is not deployed for this app's request url http://mySharePointRootWebURL.local.
var data = new SP.RequestExecutor("http://mySharePointRootWebURL.local/");
data.executeAsync({
method: "GET",
headers: { "Accept": "application/json;odata=verbose" },
url: "http://mySharePointRootWebURL.local/_api/web/lists/getbytitle(\'MyLstName\')/items",
success: function (data) { console.log('success!'); },
error: function (p1,p2,errorMessage) { console.log('Fail! :' + errorMessage); }
});
I can see that this example is not hitting the root web at all (from the app / app web).
jQuery Example
Yields:
Resource interpreted as Script but transferred with MIME type text/plain: "http://mySharePointRootWebURL.local/_api/web/lists/getbytitle(\'MyLstName\')/items&…Query19104068602353800088_1379462071044&alt=json-in-script&_=1379462071045". jquery.js:9597
Uncaught SyntaxError: Unexpected token < items:1
fail! : Error: jQuery19104068602353800088_1379462071044 was not called
$.ajax({
url: "http://mySharePointRootWebURL.local/_api/web/lists/getbytitle(\'MyListName\')/items",
type: "GET",
beforeSend: function(xhr){
xhr.setRequestHeader('Accept', 'application/json;odata=verbose'); },
headers: {"Accept":"application/json;odata=verbose"},
success: function(data){ console.log("success"); },
error: function errHandler(p1,p2,errMessage){ console.log("fail! : " + errMessage); },
dataType: 'jsonp',
crossDomain: true,
data: {
alt: 'json-in-script'
},
});
This is working as far as accessing the REST server and returning data, the problem is that the headers are not being added at all (verified in Fiddler). Without the headers the data comes back in XML. If that's how it has to be I will work with it, I guess, but I'd prefer to get JSON.
Your code doesn't look right. Here's code that wors with the cross-domain library
var executor = new SP.RequestExecutor(appweburl);
executor.executeAsync(
{
url:
appweburl +
"/_api/SP.AppContextSite(#target)/web/lists/getByTitle('Contacts')/items" +
"?#target='" + hostweburl + "'" +
"&$select=Id,FirstName,Title,WorkPhone,Email" +
"&$orderby=Title,FirstName",
method: "GET",
headers: { "accept": "application/json;odata=verbose" },
success: successHandler,
error: errorHandler
})