Why can I not generate a valid oauth-token using command-line curl for the LinkedIn API? Why can I not generate a valid oauth-token using command-line curl for the LinkedIn API? curl curl

Why can I not generate a valid oauth-token using command-line curl for the LinkedIn API?


As usual, the devil is in the tiniest of details.

In solving this problem, I used the ever wonderful Charles Proxy to spy on the requests that my ruby script was making via the oauth library.

As it turned out there were two distinct issues with how I was attempting to make requests from curl and from meteor that I discovered by spying on the successful ruby request while looking back at my code and messing with the oauth_callback Authorization header parameter to reverse engineer the problem.

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

Here are 2 distinct request authorization 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 param has a malformed querystring param. It turns out that having a query string param like ?close without a value, as in ?close=true, causes the request to be completely fubared. I still don't know exactly why, but that seems to be the case.

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 domain. It turns out that some oauth providers, linkedin being one of, don't like host names in the oauth_callback param (vs FQDN or IP addresses). Beats me why. We need to use 127.0.0.1. There's no good reason, but it just is. Lame, but true.

This one 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've replaced oauth_consumer_key and oauth_signature values with ********* for obvious reasons of protecting my keys and removing the possibility of reverse engineering of my secret.