Why can't I generate a valid oauth token using curl for command line for LinkedIn API?

When testing the LinkedIn API and trying to create a Meteor JS smart package for authentication against the LinkedIn OAuth provider, I came across a complete hurdle.

Following these directions , I was able to successfully generate an oauth_token for use in an authorization request in the form:

 https://www.linkedin.com/uas/oauth/authorize?oauth_token={oauth_token} 

When placing in a browser a marker created by a ruby ​​script that looks like this:

 require 'oauth' api_key = '{linkedin api key}' api_secret = '{linkedin api secret}' configuration = { :site => 'https://api.linkedin.com', :authorize_path => '/uas/oauth/authenticate', :request_token_path => '/uas/oauth/requestToken', :access_token_path => '/uas/oauth/accessToken' } consumer = OAuth::Consumer.new(api_key, api_secret, configuration) request_token = consumer.get_request_token puts request_token.params[:oauth_token] 

Then I can easily unload the token as a request parameter in the browser using the above URI and see the LinkedIn permission dialog.

LinkedIn window that displays with a valid token: enter image description here

Unfortunately, when you try to write a oauth_token request on the command line, the oauth_token that is generated fails when used in the same URL. In fact, this leads to the fact that the error response is 500, and the browser displays a standard 500 error window. The response does not contain additional information:

500 error

Here's a code similar to what I implemented in my curl request, linked for the new oauth_token :

 alex@alex-mac accounts-linkedin (fixes_for_meteor_0_5_4)* $ cat linkedin_oauth_gen.sh curl -X POST https://api.linkedin.com/uas/oauth/requestToken --verbose --header 'Authorization: OAuth oauth_nonce="0d9a3e40660811e2bcfd0800200c9a66",oauth_timestamp="1359019570",oauth_version="1.0",oauth_signature_method="HMAC-SHA1",oauth_consumer_key="{oauth_consumer_key}",oauth_signature="{oauth_signature}"' 

It is worth noting that I used the LinkedIn OAuth test console to create an authorization header.

This is important because I get the same problem when trying to implement similar functionality in my smart Meteor JS package.

However, my main question is why in the world I can do this using the ruby ​​code above, but when using the simple curl shell command, the marker does not look correctly generated (or LinkedIn just doesn't want to read it) ...

+6
source share
1 answer

As usual, the devil is in the smallest detail.

In solving this problem, I used the wonderful Charles Proxy to keep track of the requests that my ruby ​​script made through the oauth library.

As it turned out, there were two different problems with the way I tried to make requests from curl and from meteors, which I discovered while spying on a successful ruby ​​request, looking around at my code and tinkering with the oauth_callback Authorization header parameter to reverse process the problem.

Either one of these problems, or in combination, caused an invalid and unrecognizable oauth token. Instead of returning 401, linkedin created a token! Alas, this token was useless.

Here are two different authorization request headers that fail (with reasons after each):

 Authorization: OAuth oauth_body_hash="2jmj7l5rSw0yVb%2FvlWAYkK%2FYBwk%3D", oauth_callback="http%3A%2F%2Flocalhost%3A3000%2F_oauth%2Flinkedin%3Fclose", oauth_consumer_key="*********", oauth_nonce="SJ3DSTHLh0T4UcqzYOUOqubIeWN9FERCePm5ro35EY", oauth_signature="*********", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1359081520", oauth_version="1.0" 

In this first example, the problem is that the oauth_callback parameter has an invalid request parameter. It turns out that with a query string parameter, like ?close without a value, like in ?close=true , forces the query to be completely fubared. I still don’t know exactly why, but it seems to be happening.

 Authorization: OAuth oauth_body_hash="2jmj7l5rSw0yVb%2FvlWAYkK%2FYBwk%3D", oauth_callback="http%3A%2F%2Flocalhost%3A3000%2F_oauth%2Flinkedin%3Fclose", oauth_consumer_key="*********", oauth_nonce="SJ3DSTHLh0T4UcqzYOUOqubIeWN9FERCePm5ro35EY", oauth_signature="*********", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1359081520", oauth_version="1.0" 

In this second example, the problem is that oauth_callback has localhost in its scope. It turns out that some oauth providers connected in one of them do not like host names in the oauth_callback parameter (with FQDN or IP addresses). Spares me why. We need to use 127.0.0.1 . There is no good reason, but it’s just . Lame, but true.

It works:

 Authorization: OAuth oauth_body_hash="2jmj7l5rSw0yVb%2FvlWAYkK%2FYBwk%3D", oauth_callback="http%3A%2F%2F127.0.0.1%3A3000%2F_oauth%2Flinkedin%3Fclose%3Dtrue%26state%3D0e314d0d-a5ca-40ca-8fcd-caa1cfce3ed4", oauth_consumer_key="*********", oauth_nonce="0KBnMSMI8NNk1cXn0YyTRpUnPdnqAX7F06KEloh9bs", oauth_signature="*********", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1359082177", oauth_version="1.0" 

Note. I replaced the values ​​of oauth_consumer_key and oauth_signature with ********* for obvious reasons to protect my keys and remove the possibility of reverse engineering my secret.

+5
source

All Articles