2015-05-25 13 views
6

Ich versuche eine Last.fm-Sitzung zu autorisieren und habe Schwierigkeiten, eine Anforderung für einen Sitzungsschlüssel korrekt zu signieren.Authentifizieren mit Last.fm in Jquery - Ungültige Methodensignatur angegeben

Ich bekomme weiter Invalid method signature supplied Aber wenn ich md5 Hash, was ich glaube, dass die Abfrage außerhalb von JS bestehen sollte, bekomme ich die gleiche Signatur. Ich muss die falschen Daten in die Zeichenfolge aufnehmen, denke ich, kann aber nicht herausfinden, was.

Ich weiß, es gibt ein paar andere Fragen, und ich habe sie alle durchgelaufen, um zu sehen, was hier schief läuft, aber ich schwöre, es sieht gut zu mir aus.

Dies ist der Signaturalgorithmus und Ajax-Aufruf. Ich habe versucht, auch genügend Beispieldaten zu hinterlassen.

// 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 
} 

Kann irgendjemand sehen, dass ich hier vermisse? Ich bin absolut ratlos, warum dies kein korrekt signiertes POSTable-Objekt im angeforderten Format here zurückgibt. Vielen Dank für Ihre Zeit.

Edit: kann niemandem für ihre Zeit danken, wenn ich keinen Rat bekomme! Keiner hatte Erfahrung mit last.fm?

+0

Versuchen 'Entfernen von Daten [‚format‘] =‚json‘,' – George

+0

Danke, ich versuchen, diese werden zusammen mit der antworte unten. – TechnicalChaos

+0

Prost, obwohl etwas daneben - Ich habe meine eigene Antwort unten mit dem, was ich bezüglich der Format-Attribut gefunden habe, bearbeitet. – TechnicalChaos

Antwort

1

Also auf einige der Antworten zu testen, fand ich die Lösung. Es gab 2 Probleme. EDITED siehe unten ( Die erste

data['format'] = 'json'; 

als George Lee hingewiesen. Dank George zu entfernen, wurde zu benötigen. )

Das andere Problem war, dass ich fälschlicherweise eine Variable mit dem Namen hatte so mit dem Sein wurde POSTed der falsche Name.Die Linie

so['signature'] = hashed_sec; 

sollte

gewesen
so['api_sig'] = hashed_sec; 

Ich bemerkte dies in Pankaj Antwort aber leider den Rest seiner Antwort (das heißt einschließlich der Methode) war nicht korrekt. Durch diese 2 Änderungen wurde der Anruf aufgelöst und korrekt signiert.

Danke für alle Vorschläge!

EDIT: Nach etwas mehr spielen, habe ich festgestellt, dass

data['format'] = 'json'; 

korrekt ist, aber es nicht mit der Unterschrift gehasht erhalten. Hinzufügen von data['format'] = 'json'; zum POST-Objekt nach dem Hashing funktioniert, und in diesem Fall wird JSON im Gegensatz zu XML zurückgegeben - was die bevorzugte Methode war. Das Hinzufügen nach dem Hashing ist nirgends dokumentiert, das ich finden kann, also los gehts. Der neue Arbeits Code ist wie folgt, und dies zeigt die 2 Linien angedeutet mit --------------------

// 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 
} 
+0

Ja, ich habe irgendwo in der API-Dokumentation gesehen, dass es als JSON zurückgegeben werden kann, aber nirgends gesehen hat, wie es gemacht wird. Froh, dass du alles sortiert hast! – George

2

Nach der Untersuchung Ihrer Code und andere Beiträge im Zusammenhang mit last.fm API Anruf, fand ich, dass @george Lee in der Tat richtig ist. Sie müssen format nicht bereitstellen, während Sie die auth_sign generieren.

von Apart, dass Sie $.md5()-auth_sign String nach der Anwendung encodeURIComponent() und unescape() Funktionen anwenden müssen. So was.

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

Auch ajax Anruf während machen müssen Sie api_key, token & api_sig als data passieren. Wenn Sie jedoch Ihren Code sehen, wird Ihnen mitgeteilt, dass Sie api_key, token, format, method & signature übergeben.

So müssen Sie format, method & signature aus dem Feld von ajax Anruf entfernen.

Stattdessen müssen Sie api_key, token & api_sig an das Feld data übergeben.

So wird der endgültige Code nach dem Kommentieren der data['format'] = 'json'; Zeile so aussehen.

// 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 
    } 

Please refer to this link.

+0

Danke! Ich werde das so schnell wie möglich versuchen und Ihnen das Ergebnis mitteilen. Ich habe es ohne die Methode allein versucht, und das hat eine XML-Antwort anstelle von JSON gezeichnet, aber ich werde es mit den anderen Schritten versuchen und sehen. – TechnicalChaos

+0

Noch hatte ich leider noch keine Chance das zu testen. – TechnicalChaos

+0

Danke für die Hilfe, ich habe einen Fehler in meinem Code entdeckt, dank des Beispiels hier. – TechnicalChaos