我正在努力将LinkedIn OAuth添加到我创建的允许用户自动发布到他们的LinkedIn公开个人资料的Phonegap应用程序中。我似乎无法通过Childbrowser插件从LinkedIn REST API中检索访问令牌。为了签署我的REST API调用,我使用了JavaScript中的OauthSimple插件。无效签名LinkedIn Oauth在获取访问令牌时
当我将签名的POST发送到REST API时,我收到401 Unauthorized错误。它指定我有一个无效的签名,我无法弄清楚我的生活出了什么问题。
这是JSON响应我从LinkedIn收到的时候我做了访问令牌请求:
{"readyState":4,
"responseText":"oauth_problem=signature_invalid&
oauth_problem_advice=com.linkedin.security.auth.pub.LoginDeniedInvalidAuthTokenException%20
while%20obtaining%20request%20token%20for%20%3APOST%26
https%253A%252F%252Fapi.linkedin.com%252Fuas%252Foauth%252F
accessToken%26
oauth_consumer_key%253Dkivazo8r4xr3%2526
oauth_nonce%253D6ruTZ%2526
oauth_signature_method%253DHMAC-SHA1%2526
oauth_timestamp%253D1360525594%2526
oauth_token%253D0011aab8-0cf0-4555-ba44-304b34e4b636%2526
oauth_verifier%253D32140%2526
oauth_version%253D1.0,
"status":401,
"statusText":"Unauthorized"}
如果你想看看我的javascript,这里是我的功能:
function parametersFromUrl(url) {
var result = {};
//Remove everything up to where the parameters start. could be after # or after ?
url = url.substr(url.indexOf('?') + 1).substr(url.indexOf('#') + 1)
//Replace html escape characters
url = url.replace(/%23/g, '#').replace(/%26/g, '&').replace(/%3D/g, '=');
var parameters = url.split('&');
for(var i = 0; i < parameters.length; i++) {
var parameter = parameters[i].split('=');
result[parameter[0]] = parameter[1];
}
return result;
}
/* -- Linkedin START -- */
var Linkedin = {
init:function() {
var signatures = { consumer_key: '555555', shared_secret: '555555' };
var simple = new OAuthSimple(signatures.consumer_key, signatures.shared_secret);
Linkedin.getRequestToken(simple, signatures);
},
getRequestToken:function(simple, signatures) {
var result = simple.reset().sign({
action: 'POST',
path: 'https://api.linkedin.com/uas/oauth/requestToken',
signatures: signatures
});
console.log(result);
console.log(result.signed_url);
jQuery.ajax({
url: result.signed_url,
type: 'POST',
success: function(data) {
jQuery.extend(signatures, parametersFromUrl(data));
console.log(signatures['oauth_token']);
Linkedin.childBrowserAuthenticate(simple, signatures);
},
error: function() {
console.log('error');
}
});
},
childBrowserAuthenticate:function(simple, signatures) {
ChildBrowser.install();
var childBrowser = window.plugins.childBrowser;
var browserUrl = simple.reset().sign({
path: signatures['xoauth_request_auth_url']
}).signed_url;
browserUrl = browserUrl + '&oauth_token=' + signatures['oauth_token'];
childBrowser.showWebPage(decodeURIComponent(browserUrl));
function finish(err) {
if (err) onFailure(err);
childBrowser.onClose = null;
childBrowser.close();
}
childBrowser.onLocationChange = function(loc) {
if (loc.indexOf('oauth_problem') > -1) {
finish('User authorization error');
} else if (loc.indexOf('oauth_verifier') > -1) {
alert('good');
finish();
$.each(signatures, function(i,item) {
console.log(i);
console.log(item);
});
console.log("next");
params = parametersFromUrl(loc);
jQuery.extend(signatures, params);
$.each(signatures, function(i,item) {
console.log(i);
console.log(item);
});
Linkedin.getAccessToken(simple, signatures);
}
};
childBrowser.onClose = function() {
finish('User cancelled authorization.');
};
},
getAccessToken:function(simple, signatures) {
console.log("last");
$.each(signatures, function(i,item) {
console.log(i);
console.log(item);
});
var requestUrl = simple.reset().sign({
action: 'POST',
path: 'https://api.linkedin.com/uas/oauth/accessToken',
parameters: {
'oauth_verifier': signatures.oauth_verifier,
'oauth_token': signatures.oauth_token,
'oauth_token_secret': signatures.oauth_token_secret,
'oauth_version': "1.0"
}
}).signed_url;
console.log(requestUrl);
jQuery.ajax({
url: requestUrl,
type: 'POST',
success: function(data) {
jQuery.extend(signatures, parametersFromUrl(data));
$.each(signatures, function(i,item) {
console.log(i);
console.log(item);
});
Linkedin.getUserProfile();
},
error: function(resp) {
alert('crap');
console.log(resp);
}
});
},
getUserProfile:function() {
var result = simple.reset().sign({
action: 'GET',
path: 'https://api.linkedin.com/v1/people/~:(first-name,last-name,headline,picture-url)',
parameters: {
format: 'json'
}
});
jQuery.ajax({
url: result.signed_url,
success: function(userData) {
onSuccess(userData);
alert('success');
alert(userData);
},
error: function(resp) {
onFailure('Failed to get profile information')
}
});
}
};
/* -- Linkedin END -- */
当我做一个请求(POST)到LinkedIn REST API来获得访问令牌,我的网址是这样的:
https://api.linkedin.com/uas/oauth/accessToken?oauth_consumer_key=555555&oauth_nonce=KXuSN&oauth_signature=rk7eNjTxlhi0UOppOPfA%2BYvQ8uM%3D&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1360527087&oauth_token=206e2377-c790-49a6-839c-a996cadfbdfc&oauth_verifier=62355&oauth_version=1.0
我将oauth签名与Linkedin oauth控制台生成的签名进行了比较,他们不一样。什么可能是错的?
我用this tutorial来指导我完成整个过程。
如果您需要更多信息,请让我知道,我会添加到我的问题。
非常感谢!
因为我的应用程序是用Phonegap和Childbrowser构建的。这个库是为创建Web应用程序而制作的。子浏览器必须由javascript函数调用。除非你知道我可以如何使用这个库与Childbrowser进行交互,否则那太棒了!谢谢 – Karl 2013-02-15 17:32:24
使用这个库,就像从你的html链接到一个JavaScript文件一样简单。我不是Phonegap和childbrowser的专家,但如果你能做到这一点,那么图书馆应该工作。 – 2013-02-17 11:58:10
如果您确定自己的代码是正确的,通常OAuth无效签名问题与客户端或服务器上的时间不正确有关。 – 2013-02-17 11:58:56