在Jquery中使用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
}
任何人都可以看到我在这里失踪? 我绝对难住为什么这不按照这里要求的格式返回一个正确签名的POSTable对象。 谢谢你的时间。
编辑:不能感谢任何人的时间,如果我没有得到任何建议! 没有人对last.fm有过任何经验?
在调查了与last.fm
api调用相关的代码和其他帖子之后,我发现@george lee实际上是正确的。 生成auth_sign
时不需要提供format
。
除此之外,在应用encodeURIComponent()
和unescape()
函数之后,您需要将$.md5()
应用于auth_sign
字符串。 喜欢这个。
hashed_sec = $.md5(unescape(encodeURIComponent(ss + last_fm_data['secret'])));
同时进行ajax
调用时,您需要将api_key, token & api_sig
作为data
传递。 但看到你的代码,就会发现你传递了api_key, token, format, method & signature
。
所以你需要从ajax
调用的data
字段中删除format, method & signature
。
相反,您需要将api_key, token & api_sig
传递给data
字段。
因此,评论data['format'] = 'json';
后的最终代码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
}
请参阅此链接。
所以在测试一些响应时,我找到了解决方案。 有两个问题。 EDITED见下文(第一个需要删除
data['format'] = 'json';
正如乔治李指出的那样。 谢谢乔治。 )
另一个问题是我错误地命名了一个变量,所以被错误的名称POST。 该线
so['signature'] = hashed_sec;
本来应该
so['api_sig'] = hashed_sec;
我在Pankaj的回答中注意到了这一点,但不幸的是,他的答案的其余部分(即包括该方法)是不正确的。 进行这两项更改可以解决呼叫并正确签名。
感谢所有的建议!
编辑:经过一些更多的玩,我发现
data['format'] = 'json';
是正确的,但它不会被签名散列。 添加data['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
}
链接地址: http://www.djcxy.com/p/26479.html