Therefore, when testing some of the answers, I found a solution. There were 2 questions. EDITED see below (First had to remove
data['format'] = 'json';
as noted by George Lee . Thank you George. )
Another problem was that I incorrectly named the variable, so I was POSTed with the wrong name. Line
so['signature'] = hashed_sec;
should be
so['api_sig'] = hashed_sec;
I noticed this in Pankaj's answer, but unfortunately the rest of his answer (i.e. including the method) was wrong. Making these two changes resolved the call and signed it correctly.
Thanks for all the suggestions!
EDIT: After several games, I found that
data['format'] = 'json';
True, however, it does not receive signature hash. Adding data['format'] = 'json'; to the POST object after hashing, in which case it will return JSON rather than XML, which was the preferred method. Adding after hashing is not documented anywhere that I can find, so you go. The new working code is as follows, and it shows 2 lines indicated by the symbol --------------------
// Set elsewhere but hacked into this example: var last_fm_data = { 'last_token':'TOKEN876234876', 'user': 'bob', 'secret': 'SECRET348264386' }; // Kick it off. last_fm_call('auth.getSession', {'token': last_fm_data['last_token']}); // Low level API call, purely builds a POSTable object and calls it. function last_fm_call(method, data){ // param data - dictionary. last_fm_data[method] = false; // Somewhere to put the result after callback. // Append some static variables data['api_key'] = "APIKEY1323454"; data['method'] = method; post_data = last_fm_sign(data); // THEN ADD THE FORMAT --------------------------------------- post_data['format'] = 'json'; $.ajax({ type: "post", url: last_url, data: post_data, success: function(res){ last_fm_data[method] = res; console.log(res['key'])// Should return session key. }, dataType: 'json' }); } function last_fm_sign(params){ ss = ""; st = []; so = {}; Object.keys(params).forEach(function(key){ st.push(key); // Get list of object keys }); st.sort(); // Alphabetise it st.forEach(function(std){ ss = ss + std + params[std]; // build string so[std] = params[std]; // return object in exact same order JIC }); // console.log(ss + last_fm_data['secret']); // api_keyAPIKEY1323454formatjsonmethodauth.getSessiontokenTOKEN876234876SECRET348264386 hashed_sec = unescape(encodeURIComponent($.md5(ss + last_fm_data['secret']))); so['api_sig'] = hashed_sec; // RENAMED THIS ---------------------------- return so; // Returns signed POSTable object }