So I found my answer! Since I am using Phonegap, I can make direct JSON calls to the API without a signature library. So I directly requested the Auth Code from the API using OAuth 2.0 with the values added to the url. Here is the link to the documentation.
Invalid Signature LinkedIn Oauth while getting access token
-
09-03-2022 - |
Pregunta
I am trying dearly to add LinkedIn OAuth to a Phonegap application that I have created to allow users to automatically post to their LinkedIn public profile. I seem to be having trouble retrieving the access token from LinkedIn REST API via the Childbrowser plugin. To sign my REST API calls, I am using the OauthSimple plugin, in javascript.
When I send my signed POST to the REST API, I receive an 401 Unauthorized error. It specifies that I have an invalid signature and I can't figure out for the life of me what is wrong.
This is the json response I receive from LinkedIn when I make the request for the access token:
{"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"}
If you would like to have a look at my javascript, here are my functions:
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 -- */
When I make a request (POST) to LinkedIn REST API to get access token, my url looks like this:
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
I compared my oauth signature to the one generated by the Linkedin oauth console and they arent the same. What could be wrong?
I used this tutorial to guide me through the process.
If you need any more information, please let me know and I will add to my question.
Thank you so much!
Solución 2
Otros consejos
Why not use the Linkedin Javascript library? It does all the backend work for you, including signing requests. Place this in your header file.
<script type="text/javascript" src="http://platform.linkedin.com/in.js">
api_key: [API_KEY]
</script>
Then place this anywhere you need to show the sign-in button.
<script type="in/Login"> Hello, <?js= firstName ?> <?js= lastName ?>. </script>