Authentication with Last.fm in JQuery - Invalid Method Signature

I am trying to complete a Last.fm session and am trying to correctly sign the request for the session key.

I keep getting Invalid method signature supplied However, when I have md5 hash, I think the request should consist of outside JS, I get the same signature. I have to include the wrong data in the string, I think, but I can not understand what.

I know that there are a few more questions, and I ran them all to understand what was going on here, but I swear it looks right.

This is a signature algorithm and an Ajax call. I also tried to leave enough sample data.

 // 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['format'] = 'json'; data['method'] = method; post_data = last_fm_sign(data); $.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['signature'] = hashed_sec; // Correct when calculated elsewhere. return so; // Returns signed POSTable object } 

Anything, can anyone see me missing here? I am absolutely obsessed with why this does not return a correctly signed POSTable in the requested format here . Thank you for your time.

Edit: I can't thank anyone for their time if I don't get any advice! No one had experience with last.fm?

+6
source share
2 answers

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 } 
+1
source

After studying your code and other messages related to calling last.fm api, I found that @george lee is actually true. When creating auth_sign you do not need to specify format .

In addition, you need to apply the line $.md5() to auth_sign after applying the encodeURIComponent() and unescape() functions. Like this.

 hashed_sec = $.md5(unescape(encodeURIComponent(ss + last_fm_data['secret']))); 

Also when calling ajax you need to pass api_key, token & api_sig as data . But, seeing your code, you will find that you are passing api_key, token, format, method & signature .

Therefore, you need to remove format, method & signature from the data field of the ajax call.

Instead, you need to pass api_key, token & api_sig to the data field.

So, the final code after commenting out the string data['format'] = 'json'; will look like this.

  // 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['format'] = 'json'; data['method'] = method; post_data = last_fm_sign(data); $.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 = {}; so['api_key'] = params['api_key']; so['token'] = params['token']; 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 }); ss += last_fm_data['secret']; // console.log(ss + last_fm_data['secret']); // api_keyAPIKEY1323454formatjsonmethodauth.getSessiontokenTOKEN876234876SECRET348264386 hashed_sec = $.md5(unescape(encodeURIComponent(ss))); so['api_sig'] = hashed_sec; // Correct when calculated elsewhere. return so; // Returns signed POSTable object } 

Refer to this link.

+2
source

Source: https://habr.com/ru/post/987837/


All Articles