2015-05-25 15 views
6

Próbuję autoryzować sesję Last.fm i staram się poprawnie podpisać żądanie klucza sesji.Uwierzytelnianie za pomocą Last.fm w Jquery - Podano niepoprawny podpis metody

Wciąż otrzymuję Invalid method signature supplied Jednak gdy I md5 hash, co uważam, że kwerenda powinna składać się poza JS, otrzymuję ten sam podpis. Muszę uwzględnić błędne dane w łańcuchu, ale nie wiem, co.

Wiem, że jest jeszcze kilka innych pytań i przejrzałem je wszystkie, żeby zobaczyć, co tu jest nie tak, ale przysięgam, że wygląda to dla mnie dobrze.

To jest algorytm podpisywania i połączenie Ajax. Próbowałem też zostawić wystarczającą ilość przykładowych danych.

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

Coś, co ktoś może zobaczyć, że tu mnie brakuje? Jestem absolutnie zakłopotany, dlaczego nie zwraca poprawnie podpisanego obiektu POSTable w formacie wymaganym here. Dziękuję za Twój czas.

Edycja: nie dziękuję nikomu za poświęcony czas, jeśli nie otrzymam porady! Nikt nie miał żadnego doświadczenia z last.fm?

+0

Spróbuj usunąć dane '[„format”] =„json”;' – George

+0

Dzięki, spróbuję to wraz z odpowiedź poniżej. – TechnicalChaos

+0

Pozdrawiam, choć trochę nie tak - zredagowałem swoją własną odpowiedź poniżej z tym, co znalazłem odnośnie atrybutu formatu. – TechnicalChaos

Odpowiedz

1

Więc na testowanie niektóre odpowiedzi, znalazłem rozwiązanie. Wystąpiły 2 problemy. EDYCJI patrz niżej ( Pierwszy został konieczności usunięcia

data['format'] = 'json'; 

jak George Lee zauważył. Dzięki George. )

Innym problemem było to, że ja o nazwie zmiennej nieprawidłowo tak był pisał z złe imię.Linia

so['signature'] = hashed_sec; 

powinien być

so['api_sig'] = hashed_sec; 

Zauważyłem to w odpowiedzi Pankaj, ale niestety reszta jego odpowiedź (to znaczy w tym metody) była błędna. Dokonanie tych 2 zmian rozwiązało połączenie i podpisało je poprawnie.

Dzięki za wszystkie sugestie!

EDIT: Po trochę więcej zabawy, odkryłem, że

data['format'] = 'json'; 

jest poprawne, jednak nie dostaje mieszany z podpisem. Dodanie data['format'] = 'json'; do obiektu POST po haszowaniu działa, iw tym przypadku zwróci JSON w przeciwieństwie do XML - która była preferowaną metodą. Dodanie po haszowaniu nie jest nigdzie udokumentowane, więc mogę je znaleźć. Nowy kodeks pracy jest w następujący sposób, a to pokazuje, że 2 linie oznaczone --------------------

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

Tak, widziałem gdzieś w dokumentacji API, że można go zwrócić jako JSON, ale nigdzie nie widziałem, jak to zrobić. Cieszę się, że masz wszystko posortowane! – George

2

Po sprawdzeniu kodu i innych postów związanych z wywołaniem api last.fm, stwierdziłem, że @george lee w rzeczywistości jest poprawne. Nie musisz podawać format podczas generowania auth_sign.

Poza tym trzeba zastosować do auth_sign$.md5() ciąg po zastosowaniu encodeURIComponent() i unescape() funkcje. Lubię to.

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

Również podczas dokonywania ajax połączenia trzeba przejść api_key, token & api_sig jak data. Ale widząc twój kod, okazuje się, że mijasz api_key, token, format, method & signature.

Musisz więc usunąć format, method & signature z pola data połączenia ajax.

Zamiast tego należy podać api_key, token & api_sig do pola data.

Ostatni kod po skomentowaniu linii data['format'] = 'json'; będzie wyglądać następująco.

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

Dziękujemy! Spróbuję tego jak najszybciej i dam ci znać. Próbowałem tego bez samej metody, która narysowała odpowiedź XML zamiast JSON, ale spróbuję tego z innymi krokami i zobaczę. – TechnicalChaos

+0

Nadal nie miałem okazji przetestować tego jeszcze niestety. – TechnicalChaos

+0

Dzięki za pomoc, zauważyłem błąd w moim kodzie dzięki przykładowi tutaj. – TechnicalChaos

Powiązane problemy