Javascript 使用Jquery中的Last.fm进行身份验证-提供的方法签名无效
我正在尝试验证最后一个.fm会话,并且正在努力正确地签署会话密钥请求 我一直收到提供的Javascript 使用Jquery中的Last.fm进行身份验证-提供的方法签名无效,javascript,jquery,api,md5,last.fm,Javascript,Jquery,Api,Md5,Last.fm,我正在尝试验证最后一个.fm会话,并且正在努力正确地签署会话密钥请求 我一直收到提供的无效方法签名,但是当我用md5散列我认为查询应该包含的JS之外的内容时,我得到了相同的签名。我猜字符串中一定包含了错误的数据,但我想不出是什么 我知道还有一些其他问题,我已经把这些问题都看了一遍,看看这里出了什么问题,但我发誓我觉得这是对的 这是签名算法和Ajax调用。我也试图留下足够的样本数据 // Set elsewhere but hacked into this example: var last_fm
无效方法签名
,但是当我用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
}
任何人都能看到我在这里丢失了什么吗?我完全搞不懂为什么这不能以请求的格式返回正确签名的可邮寄对象。谢谢你抽出时间
编辑:如果我没有得到任何建议,就不能感谢任何人的时间!没有人对last.fm有任何经验?在调查了您的代码和与
last.fm
api调用相关的其他帖子后,我发现@george lee实际上是正确的。生成auth\u签名
时,不需要提供格式
除此之外,在应用encodeURIComponent()
和unescape()
函数之后,还需要将$.md5()
应用于auth\u-sign
字符串。像这样
hashed_sec = $.md5(unescape(encodeURIComponent(ss + last_fm_data['secret'])));
另外,在进行ajax
调用时,您需要将api\u key、token和api\u sig
作为data
传递。但是看到您的代码,就会发现您正在传递api\u密钥、令牌、格式、方法和签名
因此,您需要从ajax
调用的data
字段中删除格式、方法和签名
相反,您需要将api_key、token&api_sig
传递到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
}
在测试了一些回答之后,我找到了解决方案。有两个问题。
编辑见下文(
第一个是需要移除
data['format'] = 'json';
如前所述,谢谢乔治。
)
另一个问题是,我错误地命名了一个变量,因此使用了错误的名称发布。线路
so['signature'] = hashed_sec;
应该是
so['api_sig'] = hashed_sec;
我在Pankaj的回答中注意到了这一点,但不幸的是,他的其余回答(即包括方法)是不正确的。进行这两项更改解决了呼叫并正确签名
谢谢你的建议
编辑:
再玩一会儿,我发现
data['format'] = 'json';
是正确的,但是它不会与签名一起散列。
添加数据['format']='json'代码>在散列工作后返回POST对象,在本例中,将返回JSON而不是XML,这是首选方法。散列后添加在我能找到的任何地方都没有文档记录,所以就这样吧。
新的工作代码如下所示,这显示了用----------------
// 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
}
尝试删除数据['format']='json'代码>谢谢,我将与下面的答案一起尝试。干杯,尽管有点不对劲-我已经用我找到的关于格式属性的内容编辑了下面我自己的答案。谢谢!我会尽快尝试,并让你知道结果。我在没有单独使用该方法的情况下尝试了该方法,并得到了一个XML响应,而不是JSON,但我将在其他步骤中尝试并查看。遗憾的是,仍然没有机会测试该方法。感谢您的帮助,多亏了这里的例子,我在代码中发现了一个错误。是的,我确实在API文档中看到它可以作为JSON返回,但没有看到如何返回。很高兴你把它都整理好了!