LinkedIn Developer Network

Currently Being Moderated

OAuth Authentication

VERSION 14  Click to view document history

Created on: Oct 20, 2009 4:20 PM by Lucian - Last Modified:  Dec 7, 2009 9:27 AM by Taylor Singletary

 

Known Issues

  • Presently, LinkedIn OAuth only supports passing OAuth parameters in headers and not yet in the query parameters of the URL. We will add query parameter support soon.

  • Two-legged OAuth support for public profile is currently unsupported.

 

The LinkedIn API utilizes OAuth as its authentication method. OAuth is a standard model for negotiating developer authorization  and granting access on behalf of specific users for performing API requests. One of OAuth's strengths is the availability of many third party and open source libraries, allowing developers to authenticate with LinkedIn quickly and in a similar manner to how they may authenticate with services like Twitter, Google, Yahoo, and Netflix.

 

Authorization in the LinkedIn APIs

The LinkedIn website requires a user login. Because most of the content is presented from the end user perspective, we need to know who is requesting the information. When you view a profile, for example, we need to know who you are to tell you whether you are connected, who connects you, and select which communications paths you have to that profile.

The same is true of the APIs. Whether you ask for a user's profile, connections, network updates, or want to post messages, we need to know the user for the request.

Further, good privacy practice requires us to ensure an end user grants your application access to use their LinkedIn account. We want our end users to be in control of their information and their LinkedIn accounts, and so only an individual user can grant your application access to make API calls on their behalf.

 

The OAuth Flow

Our implementation of OAuth strictly follows the OAuth standard. You can read all about the OAuth standard and study the spec, but in general, it includes the following flow:

  1. You get an API key from LinkedIn. This is also called a Consumer Key in OAuth terminology.
  2. You build a feature into your site that leverages the user's LinkedIn network.
  3. Your user clicks on your UI to request to use that feature.
  4. You make a call to LinkedIn to ask to use our authentication. This is called getting a Request Token.
  5. LinkedIn replies with an OAuth Token indicating that you can use the authentication system.
  6. You send your user to a LinkedIn URL. That URL includes the OAuth Token you got and a few other parameters such as a URL for LinkedIn to return the user to after granting access.
  7. The user grants access to your application by signing into that page.
  8. Upon successful signon, LinkedIn will return the user to your site.
  9. You will then make a call to LinkedIn to get an Access Token.
  10. LinkedIn replies with an Access Token for the user. You use that Access Token for any API calls to LinkedIn to identify the user on whose behalf you are making the call.

 

So, every call will come into LinkedIn with two identifiers:

  • Your API key, identifying you and your application
  • The Access Token, identifying the user’s account you are requesting the information from

 

You can read all about the OAuth process on the OAuth standards site.

You may also gain some perspective by looking at other OAuth providers such as Yahoo and this Beginner's Guide to OAuth.

 

This diagram details the OAuth 1.0a flow:

Oauth_diagram.png

Using OAuth from the Desktop and Mobile

The OAuth spec provides for implementations for web applications but also covers many other environments such as desktop, mobile, and even Chumbies.

For most desktop and mobile applications, a modification of the standard web flow will work very well. The application should send the user to the agreement screen, following steps 1-7. You should use a redirect to a static page you construct that instructs the user to return to your application and follow whatever process is appropriate for them to keep using your application. Typically, that will be clicking a button to say "Finished Granting Access." After the user indicates that they have completed granting access, you can follow the final steps 9 and 10.

LinkedIn's OAuth Details

LinkedIn's OAuth follows the standard exactly. Meaning that any standard OAuth libraries in your language of choice should just work out of the box. But you do need to know a few things about our OAuth implementation to use your libraries:

  • LinkedIn API key and secret: you can get these from the developers.linkedin.com site
  • The site: https://api.linkedin.com. Some libraries will have you enter this root URL.
  • Request token path: /uas/oauth/requestToken
  • Access token path: /uas/oauth/accessToken
  • Authorize path: /uas/oauth/authorize

Anatomy of an OAuth Request

While it's not recommended to use SSL for all API operations, you must use SSL for all authentication steps.

 

Generating Base Strings

When generating a base string in any step of the OAuth process, each value of the base string needs to be URL escaped (including the equals signs).

 

Establish a requestToken

The first step to authorizing a LinkedIn member is requesting a requestToken. This request is done with an HTTP POST.

For the requestToken step, the following components should be present in your string to sign:

Your base string should end up looking something like this if you're using a callback:

POST&https%3A%2F%2Fapi.linkedin.com%2Fuas%2Foauth%2FrequestToken&oauth_callback%3Dhttp%253A%252F%252Flocalhost%253A3000%252Foauth_consumers%252Ftaylor_singletary%252Fcallback%26oauth_consumer_key%3DdTgSkaRKZjEnS1vAUu6e7-aYC00UilBTwnXHpLH7NyL2e-klzBC1a4TKCnSgClWV%26oauth_nonce%3DoqwgSYFUD87MHmJJDv7bQqOF2EPnVus7Wkqj5duNByU%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1259178158%26oauth_version%3D1.0

You then sign this base string with your consumer_secret, computing a signature. In this case the signature would be "yp39fCS0UJiI1nnmsE06C4A7AA8="

Now you take the signature you generated, along with oauth_nonce, oauth_callback, oauth_signature_method, oauth_timestamp, oauth_consumer_key, and oauth_version and create an HTTP Authorization header. For this request, that HTTP header would look like:

Authorization: OAuth oauth_nonce="oqwgSYFUD87MHmJJDv7bQqOF2EPnVus7Wkqj5duNByU", oauth_callback="http%3A%2F%2Flocalhost%3A3000%2Foauth_consumers%2Ftaylor_singletary%2Fcallback", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1259178158", oauth_consumer_key="dTgSkaRKZjEnS1vAUu6e7-aYC00UilBTwnXHpLH7NyL2e-klzBC1a4TKCnSgClWV", oauth_signature="yp39fCS0UJiI1nnmsE06C4A7AA8%3D", oauth_version="1.0"

Please note, that the HTTP header is a single header -- not an HTTP header for each component. You can optionally supply a realm="http://api.linkedin.com".

As a response to your request for a requestToken, your requestToken will be in the "oauth_token" response field, a validation that we acknowledged your callback with the "oauth_callback_confirmed" field, and an oauth_token_secret.

An example response would look like:

oauth_token=94ab03c4-ae2c-45e4-8732-0e6c4899db63&oauth_token_secret=be6ccb24-bf0a-4ea8-a4b1-0a70508e452b&oauth_callback_confirmed=true

 

Redirect the User to our Authorization Server

Now that you have a requestToken, you need to use that requestToken to forward the user to our authorization server where they'll authorize your application. Because LinkedIn runs on OAuth 1.0a, you must not add an oauth_callback parameter to this step. You need only forward the user to https://api.linkedin.com/uas/oauth/authorize with your requestToken specified as a query parameter called "oauth_token".

Once you've redirected the user to this step, they'll authorize your application and LinkedIn will either redirect the user to the callback URL you specified in the requestToken step OR the user will be directed to a page containing the OAuth Verifier step if you are performing an out-of-band style request.

If the user is redirected to your server via the OAuth callback URL, you'll get two fields back: oauth_token and an oauth_verifier. The oauth_token will be the same requestToken you received in the first step. You'll want to temporarily store the oauth_verifier so that you can use it as part of your accessToken request in the next step.

In the examples used so far, the callback specified in the requestToken step would receive a request like this:

http://localhost:3000/oauth_consumers/taylor_singletary/callback?oauth_token=94ab03c4-ae2c-45e4-8732-0e6c4899db63&oauth_verifier=98295

If you're performing an out of band request cycle, this is the step where the user returns to your application and will hand-enter the OAuth verifier code, which you'll then pass back to us in the next step. Otherwise, all of these steps remain the same.

 

Requesting an Access Token

We're almost done with the authorization dance. This is the last step where you obtain an access token that actually gives you the agency to make requests on behalf of the LinkedIn member.

For the requestToken step, the following components should be present in your string to sign:

Your base string should end up looking something like this if you're using a callback:

POST&https%3A%2F%2Fapi.linkedin.com%2Fuas%2Foauth%2FaccessToken&oauth_consumer_key%3DdTgSkaRKZjEnS1vAUu6e7-aYC00UilBTwnXHpLH7NyL2e-klzBC1a4TKCnSgClWV%26oauth_nonce%3Dwm2h9DH3Njoe62ezioNQS0qPfD11MH4w4paJufkk%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1259178208%26oauth_token%3D94ab03c4-ae2c-45e4-8732-0e6c4899db63%26oauth_verifier%3D27871%26oauth_version%3D1.0

You then sign this base string with your consumer_secret, computing a signature. In this case the signature would be "srWAOowk6Tk4irC9pEMUa7Tx+Bc="

Now you take the signature you generated, along with oauth_nonce, oauth_signature_method, oauth_timestamp, oauth_consumer_key, oauth_token, and oauth_version to create an HTTP Authorization header. For this request, that HTTP header would look like:

Authorization: OAuth oauth_nonce="wm2h9DH3Njoe62ezioNQS0qPfD11MH4w4paJufkk", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1259178208", oauth_consumer_key="dTgSkaRKZjEnS1vAUu6e7-aYC00UilBTwnXHpLH7NyL2e-klzBC1a4TKCnSgClWV", oauth_token="94ab03c4-ae2c-45e4-8732-0e6c4899db63", oauth_verifier="27871", oauth_signature="srWAOowk6Tk4irC9pEMUa7Tx%2BBc%3D", oauth_version="1.0"

Please note, that the HTTP header is a single header -- not an HTTP header for each component. You can optionally supply a realm="http://api.linkedin.com".

As a response to your request for an accessToken, your accessToken will be in the "oauth_token" field and an oauth_token_secret.

An example response would look like:

oauth_token=f862f658-ad89-4fcb-995b-7a4c50554ff6&oauth_token_secret=a252d40e-f7f0-4f31-a362-3451e168d5a5

If you've gotten this far, you now have an accessToken. Congratulations, you've now accomplished most of the heavy lifting with OAuth.

 

Your First API Request

The first thing you'll likely want to do is retrieve the profile for the member who just gave your application access. Like all the previous steps, this involves preparing a request by creating a base string, signing the base string with your consumer_secret, and then making a simple request with an OAuth Authentication HTTP header.

Let's get a very basic version of this member's profile.

Using the accessToken we received in the last step, the signature base string should look something like:

GET&https%3A%2F%2Fapi.linkedin.com%2Fv1%2Fpeople%2F~&oauth_consumer_key%3DdTgSkaRKZjEnS1vAUu6e7-aYC00UilBTwnXHpLH7NyL2e-klzBC1a4TKCnSgClWV%26oauth_nonce%3DLpggMEZQYFkdTmrw0OixdZLMc6DdjNWDywsIULxVRwo%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1259182582%26oauth_token%3Df862f658-ad89-4fcb-995b-7a4c50554ff6%26oauth_version%3D1.0

Signing this with a consumer_secret results in a signature. In my case, this signature was "udXNypHc+baM0FP1xRdXeyKI2/o=". Now I take that signature and generate an HTTP Authorization header:

Authorization: OAuth oauth_nonce="LpggMEZQYFkdTmrw0OixdZLMc6DdjNWDywsIULxVRwo", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1259182582", oauth_consumer_key="dTgSkaRKZjEnS1vAUu6e7-aYC00UilBTwnXHpLH7NyL2e-klzBC1a4TKCnSgClWV", oauth_token="f862f658-ad89-4fcb-995b-7a4c50554ff6", oauth_signature="udXNypHc%2BbaM0FP1xRdXeyKI2%2Fo%3D", oauth_version="1.0"

As a result of a successful request, I get an XML body as a response:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<person>
  <first-name>Taylor</first-name>
  <last-name>Singletary</last-name>
  <headline>Technical Evangelist at LinkedIn</headline>
  <site-standard-profile-request>
    <url>http://www.linkedin.com/profile?viewProfile=&amp;key=3308337&amp;authToken=REQa&amp;authType=name</url>
  </site-standard-profile-request>
</person>

This details the full request cycle for a typical OAuth transaction.

24,020 Views Tags: oauth, authentication, login, authorization
Average User Rating
(5 ratings)

Having Problems?

If you would like to leave a comment, please log in with your LinkedIn account credentials.

howardlee howardlee  says:

the timestamp span is  <= 300 seconds

Viscus Nishant Viscus Nishant  says:

Hi,

     Any one can give me the code to implement OAuth using ASP.NET and C#

 

Thanks

Albert Ritmeester Albert Ritmeester  says:

@Viscus Nishant

You could take a look at devdefined-oauth. It is finally the best OAuth implementation for csharp I found.

Vincent Ip Vincent Ip  says:

What is the consumer secret key used to calculate the signature in the "Establish a request Token" section?  I just wanted this to validate that I'm performing the operations for the signature correctly.

Vincent Ip Vincent Ip  says in response to Vincent Ip:

nevermind, i was able to plug in my own values for the consumer public and private keys and generate a signature at this website.

 

http://term.ie/oauth/example/client.php

Matthew McDermott Matthew McDermott  says:

WHY?

 

Why is the "First API Request" HTTPS https://api.linkedin.com/v1/people/~ when all the Profile API documentation is "HTTP"??

Lucian Lucian  says in response to Matthew McDermott:

There's no real reason for this. All the APIs allow access via HTTP or HTTPs.

Derek B Derek B  says:

error on the page

Under Request Access Token it says

"For the requestToken step,"

Should say "For the accessToken step,"

John Michaels John Michaels  says:

Are there any websites I can look at which use this API currently? Thanks

Alok Bhargava Alok Bhargava  says:

I am able to generate an accessToken successfully as well as access my profile. The question is how can I reuse the accessToken in time? If I select "grant application access until revoked" what should I do to reuse the accessToken next time?

 

Thanks,

Alok

Taylor Singletary Taylor Singletary  says in response to Alok Bhargava:

The accessToken and token_secret for a member should be retained in a database, that way you can re-use it to make API calls on the authorizing member's behalf whenever required. The time duration specified on the authorization scheme relates to the duration of time that access token will be valid without you having to go through the OAuth dance again to receive a new access token. When the access token is invalid and you make an API request with it, you'll get a 401 Unauthorized. A member can expire any token at any time using their Accounts & Settings pages.

Michael Lim Michael Lim  says:

Minor typo under "Requesting an Access Token".  Immediately beneath the blue "POST" box under this section, it reads:

"For the requestToken step,...".  I think you meant "For the accessToken step,..."

Janek Hiis Janek Hiis  says:

Isn't there another typo in the "You'll want to temporarily store the oauth_verifier" and it should be "You'll want to temporarily store the oauth_token_secret" because otherwise the call to accessToken will return error "oauth_problem=signature_invalid". It took me quite a whilte to figure out that when requesting accessToken one also needs the "oauth_token_secret" to sign the request.

Maybe it would help to include the requirement for "oauth_token_secret" into the process?

Bookmarked By (3)

More Like This

  • Retrieving data ...