9
votes

It works if and only if the user is signed into LinkedIn at the time of making the OAuth2 request.

If the user is not signed in then we encounter an error.

Sequence of our actions:

  • successfully fetch the fresh access token
  • using the access token, post to the api endpoint https://api.linkedin.com/v1/people/\~

After this we receive a 401 with the following content:

{
  "errorCode": 0,
  "message": "Unable to verify access token",
  "requestId": "C0DUCX81SA",
  "status": 401,
  "timestamp": 1421946470523
}

Sometimes, after some time passed, a retry with the same Access Token gives a 200. Sometimes not.

If the user logs in to LinkedIn during this "401 period" then magically the previously fetched access token starts to work.

I am at a loss how to solve this, as it seems to be an issue at LinkedIn.

Has anybody any suggestions or did anybody see this behavior before?

We tried cookie settings, wait periods before our request etc.

We are adding LinkedIn OAuth2 authentication to Zotonic [1], but are now stuck with a non-working module.

[1] http://zotonic.com/

Edit:

Someone referred to two discussions at LinkedIn. His reply now regretfully disappeared from the discussion below.

These are the links:

https://developer.linkedin.com/forum/unable-verify-access-token

https://developer.linkedin.com/forum/unauthorized-invalid-or-expired-token-immediately-after-receiving-oauth2-token

I have tried all suggestions in these discussions, to no avail.

Edit #2:

Checking the first discussion at LinkedIn shows that I am not the only one having these consistency issues. Something at LinkedIn is going wrong if the user has cleared cookies or has to sign in to LinkedIn during the OAuth "dance" https://developer.linkedin.com/forum/unable-verify-access-token#comment-36950

Update

Solved, thanks to Matthijs Bierman, see answers below.

10

10 Answers

21
votes

For me the https://api.linkedin.com/v1/people/~?format=json&oauth2_access_token=[accessToken] didn't work.

Adding reguest header

Authorization: Bearer [accessToken]

didn't work until I went through linked in sdk and tested and found out that they also require you to add request header

x-li-src: msdk

With those two headers the call https://api.linkedin.com/v1/people/~?format=json worked.

Hopefully Linkedin fixes this undocumented requirement soon...

6
votes

We talked on the phone, turns out you're running into the same problem as here. LinkedIn doesn't accept the Authentication header and expects a request parameter: oauth2_access_token.

5
votes

AccessToken from mobile SDK gives this error:

You will not face any issue with accessTokens generated using web OAuth 2.0 protocol. This problem occur only with mobile(iOS/Android) SDK, when the accessToken is used by back-end to fetch user details.

Solution: provide below 2 headers

  1. Authorization
  2. x-li-src (skip for web)

for example:

Url: https://api.linkedin.com/v1/people/~?format=json

Header(s):

Authorization: Bearer AQVYqTNB3bFRAIatBcp4hM1r-......

x-li-src:  msdk 

Note:

If AccessToken is generated using OAuth 2.0, you can use the same above api by removing just the second header(x-li-src) .

3
votes

Same here, every time I was getting new access_token I had to wait couple minutes until it was valid. This was unacceptable.

I took a look how different sites do the SignIn with LinkedIn and here is a solution that worked for me.

When exchanging AUTH_CODE in order to get ACCESS_TOKEN use GET method instead of POST, eg:

GET https://www.linkedin.com/oauth/v2/accessToken?client_id=yourClientId&client_secret=yourClientSecret&grant_type=authorization_code&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2FlinkedInLogin&code=AQQGx11-p1uaQWz2YBWHBcskaGrVrEDeFUo4O2vjolFaKaQ89UhGlR27_yDACNLoxDmYi7AR5sCplwsHLD_ERAVsscFozo-qRl032aFnj2UcUoPjCfo

Grails integration with LinkedIn OAuth2 example: https://github.com/rgrebski/samples/tree/master/grails-linkedin-integration

2
votes

With the help of Matthijs Bierman we found a fix for our problem.

We authenticated with an Authorization: Bearer .... header. If we use a oauth2_access_token query argument instead then it works in both the use cases with and without a signed-in LinkedIn user.

Conclusion: don't use the Authorization header and use the oauth2_access_token query argument instead.

1
votes

I am seeing this same problem; however, the query param is not working for me.

It is characterized just as the question described: 1) I have a valid token 2) The user is logged out of linkedin 3) The request for the user profile fails 4) Wait five minutes and it succeeds

You can see my request/response below:

$ curl -v  "https://api.linkedin.com/v1/people/~?format=json&oauth2_access_token=$LI_AT"
* Hostname was NOT found in DNS cache
*   Trying 108.174.10.12...
* Connected to api.linkedin.com (108.174.10.12) port 443 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
* Server certificate: tablet.linkedin.com
* Server certificate: DigiCert SHA2 Secure Server CA
* Server certificate: DigiCert Global Root CA
> GET /v1/people/~?format=json&oauth2_access_token=[**obscurred for security sake**] HTTP/1.1
> User-Agent: curl/7.37.1
> Host: api.linkedin.com
> Accept: */*
> 
< HTTP/1.1 401 Unauthorized
* Server Apache-Coyote/1.1 is not blacklisted
< Server: Apache-Coyote/1.1
< x-li-request-id: LZ2X5Y9DCC
< Date: Thu, 20 Aug 2015 16:12:52 GMT
< Vary: *
< x-li-format: json
< Content-Type: application/json;charset=UTF-8
< Content-Length: 142
< X-Li-Fabric: prod-ltx1
< Connection: keep-alive
< X-Li-Pop: prod-lva1
< X-LI-UUID: lS7xYKc3/BNAj0nmNSsAAA==
< Set-Cookie: lidc="b=TB76:g=111:u=47:i=1440087172:t=1440094069:s=AQHPHzjyg93X3bnT8KuNvThuwQo5buSS"; Expires=Thu, 20 Aug 2015 18:07:49 GMT; domain=.linkedin.com; Path=/
< 
{
  "errorCode": 0,
  "message": "Unable to verify access token",
  "requestId": "LZ2X5Y9DCC",
  "status": 401,
  "timestamp": 1440087172914
* Connection #0 to host api.linkedin.com left intact
}
1
votes

I tried all above solutions, but didn't work with me. I changed my url from

https://www.linkedin.com/oauth/v2/ 

to

https://www.linkedin.com/uas/oauth2/

it worked properly.

0
votes

The authenticated state of the user on LinkedIn.com (whether or not they're logged in) doesn't have an affect on a valid OAuth access token. In other words, the user can log out of LinkedIn.com and that token should still work until it's either revoked or expired.

Is there a possibility that you're generating a new token? That would render the previous one invalid. That error message you've shared is usually caused when a token has been refreshed and you're making an API call with the previous token

0
votes

None of the above worked for me. Anyone knows if there is a solution for that? sometimes its working and sometimes not without any change of code.

0
votes

https://api.linkedin.com/v1/people/~?format=json&oauth2_access_token=<token>

By default, it's return response in XML, adding format=json.