Tec*_*aos 9 javascript api jquery md5 last.fm
我正在尝试授权Last.fm会话,并且正在努力正确签署会话密钥请求.
我一直收到Invalid method signature supplied但是当我md5哈希我认为查询应该包含在JS之外时,我得到相同的签名.我必须在字符串中包含错误的数据,但我无法弄清楚是什么.
我知道还有一些其他的问题,我已经仔细研究了这些问题,看看这里出了什么问题,但我发誓看起来对我来说是正确的.
这是签名算法和Ajax调用.我也试图留下足够的样本数据.
// 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
}
Run Code Online (Sandbox Code Playgroud)
任何人都可以看到我在这里失踪?我绝对难以理解为什么这不会以此处请求的格式返回正确签名的POSTable对象.谢谢你的时间.
编辑:如果我没有得到任何建议,不能感谢任何人的时间!没有人有过last.fm的经验吗?
在调查了您的代码和其他与last.fmapi 调用相关的帖子后,我发现 @george lee 实际上是正确的。你并不需要提供format而产生的auth_sign。
除此之外,您需要在应用和函数之后应用$.md5()到auth_sign字符串。像这样。encodeURIComponent()unescape()
hashed_sec = $.md5(unescape(encodeURIComponent(ss + last_fm_data['secret'])));
Run Code Online (Sandbox Code Playgroud)
此外,在ajax拨打电话时,您需要通过api_key, token & api_sigas data。但是看到您的代码,表明您正在通过api_key, token, format, method & signature.
所以你需要format, method & signature从调用data字段中删除ajax。
相反,您需要传递api_key, token & api_sig到该data领域。
所以注释该data['format'] = 'json';行后的最终代码将如下所示。
// 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
}
Run Code Online (Sandbox Code Playgroud)
因此,在测试一些响应时,我找到了解决方案。有 2 个问题。编辑见下文(第一个需要删除
data['format'] = 'json';
Run Code Online (Sandbox Code Playgroud)
正如乔治·李指出的那样。谢谢乔治。)
另一个问题是我错误地命名了一个变量,因此使用错误的名称进行发布。线路
so['signature'] = hashed_sec;
Run Code Online (Sandbox Code Playgroud)
本来应该
so['api_sig'] = hashed_sec;
Run Code Online (Sandbox Code Playgroud)
我在 Pankaj 的答案中注意到了这一点,但不幸的是他的答案的其余部分(即包括方法)是不正确的。进行这两项更改解决了呼叫并正确签名。
感谢所有的建议!
编辑:再玩一些之后,我发现
data['format'] = 'json';
Run Code Online (Sandbox Code Playgroud)
是正确的,但是它不会与签名一起进行哈希处理。在哈希工作后添加data['format'] = 'json';到 POST 对象,在本例中将返回 JSON,而不是 XML - 这是首选方法。在我能找到的任何地方都没有记录散列后添加,所以就这样吧。新的工作代码如下,其中显示了 2 行--------------------
// 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
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
718 次 |
| 最近记录: |