LinkedIn Authentication and Fetching User Data from API

Yiğit Kemal Erinç
6 min readDec 14, 2019

--

In this article, we are going to take a look at how we can allow our users to log in by their LinkedIn profiles by implementing the Authorization Code Flow. We will also see how to fetch the user’s data from the LinkedIn API.

Configure your application

Before we get started, you need to go to LinkedIn Developers Page, and create an app to get API keys, by clicking the Create App button. You can see the Create App button at the right upper corner below your profile picture.

Creating an App from LinkedIn Developers

After you click the button, you will be asked a series of questions. You need to enter your company name and App name, I also suggest you to upload a logo that will be displayed on the login page. You will see the below page after successfully creating your App. You need to go to Auth section. You can see your Client ID and Secret here.

Configure Redirect URLs

On this page, we need to add Redirect URLs. User is going to be redirected to one of these URLs (Specified in your Access Code request) after they are successfully logged in. I set it to localhost:8080 where my application’s home page resides in the development server.

Request an Authorization Code

Now that we are all set, we can request an Authorization Code. Later in this process, this Authorization code is going to be exchanged with Access Token to get access to user’s data. To request the Authorization Code, we need to direct the client’s browser to LinkedIn’s OAuth 2.0 authorization page, where the member either accepts or denies your application’s permission request.

Here is a sample request:

GET https://www.linkedin.com/oauth/v2/authorization?response_type=code&client_id={your_client_id}&redirect_uri=https%3A%2F%2Fdev.example.com%2Fauth%2Flinkedin%2Fcallback&state=fooobar&scope=r_liteprofile%20r_emailaddress%20w_member_social

Your application will set the parameters in the URL and redirect the user to the URL. Let's go over the parameters to learn what they mean.

response_type: The value of this field should always be code

client_id: Your application’s Client ID on LinkedIn Auth page, see the above image. It is not best practice but you can hardcode this in your application’s frontend. Check security best practices from here.

redirect_uri: This is where your users are going to be redirected after login is successful, value of this parameter must match with one of the Redirect URLs in your Application Configuration (LinkedIn Auth page).

state: A unique string value of your choice that is hard to guess. Used to prevent CSRF. It is not required but recommended. You can use a randomly generated string for better security.

scope: LinkedIn API uses a list of member permissions, in this example we need r_liteprofile, r_emailaddress and w_member_social, you can check the permission list and change it if you like.

My application’s API request

You can use a button to redirect user to this URL to log in. Your user will see a page like this with your app’s logo on right. LinkedIn info part will differ depending on your app’s scope setting. This was my app’s settings in internship project.

After clicking the Allow button, user will be redirected to specified redirect_uri with a Code appended to URL.

URL will look like this: http://localhost:8080?code=129asfsd...

This code is going to be exchanged with the access token to fetch the user data. This token expires in a short time (should be around 30 mins) so you should not store it, instead you exchange it with Access Token and you can store that one.

Exchanging the Code with Access Token

Congratulations, if you have reached this step, you have successfully got the Code. We still need an Access Token to register or login a user with their profile information and fetch that information from LinkedIn API.

I used Java Spring Boot for my Backend so example will be in Java, you can use any language you want. After you get the access code, you can parse from the URL and send it to a controller in backend. In the backend, what you need to do is, firstly check if the user is already registered (exists in your database), if not send a request to LinkedIn API for Access Token and save the token with User information to your database and return the user id to your frontend to log the user in.

Here is my controller that waits for the POST request from my frontend.

@PostMapping("/exchange-token")
public ResponseEntity<String> exchangeLinkedInToken(@RequestParam("code") String authorizationCode) throws Exception {
try {
String token = candidateLinkedInService.exchangeLinkedInToken(authorizationCode);
return new ResponseEntity<>(token, HttpStatus.OK);
} catch (NotFoundException e1) {
return new ResponseEntity<>("", HttpStatus.NOT_FOUND);
} catch (LinkedInAccessTokenExpiredException e2) {
return new ResponseEntity<>("", HttpStatus.CONFLICT);
}
}

In order to get the Access Token, you should send a GET request to below URL.

"https://www.linkedin.com/oauth/v2/accessToken?grant_type=authorization_code&code="
+ authorizationCode + "&redirect_uri=" + REDIRECT_URI + "&client_id="
+ CLIENT_ID + "&client_secret=" + CLIENT_SECRET

You can hardcode REDIRECT_URI, CLIENT_ID and CLIENT_SECRET, your token will be sent to backend from your frontend, hopefully over HTTPS.

You can see my Service method that takes care of the exchange.

private String getAccessToken(String accessTokenUri) throws JSONException, LinkedInAccessTokenExpiredException {
RestTemplate restTemplate = new RestTemplate();

try {
String accessTokenRequest = restTemplate.getForObject(accessTokenUri, String.class);
JSONObject jsonObjOfAccessToken = new JSONObject(accessTokenRequest);

return jsonObjOfAccessToken.get("access_token").toString();
} catch (HttpClientErrorException e) {
throw new LinkedInAccessTokenExpiredException();
}
}

Also here is a request example from Postman

Fetching User’s Data from LinkedIn API

After this part, you can use the Access Token to make authorized requests on User’s behalf. Unfortunately, current API only allows you to fetch full name, email and profile picture.

Fetching Full Name

To fetch the user’s full name, you need to send a GET request to https://api.linkedin.com/v2/me with Authorization field set to Bearer {token}. See the example in Postman, be careful about format.

Fetching Email

Same procedure applies for the Email with a change in URL. You need to send the request to: https://api.linkedin.com/v2/emailAddress?q=members&projection=(elements*(handle~)) with your auth header is set.

Fetching Profile Image

Apply the same procedure with URL: https://api.linkedin.com/v2/me?projection=(id,profilePicture(displayImage~:playableStreams)). You can parse the JSON at your backend.

Conclusion

In this article, we learned how to register our app to LinkedIN API, how to get an Access Code, exchange it with an Access Token and fetch user’s data. If you want to inspect the whole backend process, you can view the full backend code in my Github repository. Thank you for reading!

--

--