LinkedIn is one of the most widely used professional networks, and integrating it into your web application can unlock valuable features such as social login, access to user details, and professional data sharing. In this guide, we’ll walk through how to set up LinkedIn API integration, enable login, and fetch user profile information.
Step 1: Create a LinkedIn Developer Application
- Go to the LinkedIn Developer Portal.
- Sign in with your LinkedIn account.
- Click Create App.
Fill in details like:
- App name
- Company name
- App logo
- Business email
Once created, you’ll get:
You’ll also need to configure the Redirect URL (e.g., https://yourdomain.com/auth/linkedin/callback) where LinkedIn will send users after login.
Step 2: Configure OAuth 2.0 Authorization
LinkedIn uses OAuth 2.0 for authentication. The flow is as follows:
Redirect the user to the LinkedIn authorization URL:
https://www.linkedin.com/oauth/v2/authorization
with query parameters:
response_type=code
client_id=YOUR_CLIENT_ID
redirect_uri=YOUR_REDIRECT_URL
scope=r_liteprofile r_emailaddress
Example:
https://www.linkedin.com/oauth/v2/authorization?response_type=code&client_id=YOUR_CLIENT_ID&redirect_uri=https://yourdomain.com/auth/linkedin/callback&scope=r_liteprofile%20r_emailaddress
Once the user approves, LinkedIn redirects back with a code in the URL.
Step 3: Exchange Authorization Code for Access Token
Use the code to request an access token:
POST request:
https://www.linkedin.com/oauth/v2/accessToken
Headers/Body:
grant_type=authorization_code
code=AUTHORIZATION_CODE_FROM_STEP_2
redirect_uri=YOUR_REDIRECT_URL
client_id=YOUR_CLIENT_ID
client_secret=YOUR_CLIENT_SECRET
Response:
{
"access_token": "YOUR_ACCESS_TOKEN",
"expires_in": 5184000
}
Step 4: Fetch User Profile Details
With the access token, you can now fetch user details using LinkedIn’s API.
Basic Profile
GET https://api.linkedin.com/v2/me
Authorization: Bearer YOUR_ACCESS_TOKEN
Response:
{
"id": "abcd1234",
"localizedFirstName": "John",
"localizedLastName": "Doe"
}
Email Address
GET https://api.linkedin.com/v2/emailAddress?q=members&projection=(elements*(handle~))
Authorization: Bearer YOUR_ACCESS_TOKEN
Response:
{
"elements": [
{
"handle~": {
"emailAddress": "*Emails are not allowed*"
}
}
]
}
Step 5: Implement Login Flow in Your Web App
- Add a Login with LinkedIn button on your frontend.
- Redirect users to the authorization URL (Step 2).
- Handle the callback to get the
code.
- Exchange
code for an access token (Step 3).
- Fetch profile and email details (Step 4).
- Store user information in your database and start their session.
Example in Node.js + Express
import express from "express";
import axios from "axios";
const app = express();
app.get("/auth/linkedin", (req, res) => {
const authUrl = `https://www.linkedin.com/oauth/v2/authorization?response_type=code&client_id=${process.env.LINKEDIN_CLIENT_ID}&redirect_uri=${process.env.LINKEDIN_REDIRECT_URI}&scope=r_liteprofile%20r_emailaddress`;
res.redirect(authUrl);
});
app.get("/auth/linkedin/callback", async (req, res) => {
const code = req.query.code;
const tokenResponse = await axios.post("https://www.linkedin.com/oauth/v2/accessToken", null, {
params: {
grant_type: "authorization_code",
code: code,
redirect_uri: process.env.LINKEDIN_REDIRECT_URI,
client_id: process.env.LINKEDIN_CLIENT_ID,
client_secret: process.env.LINKEDIN_CLIENT_SECRET
}
});
const accessToken = tokenResponse.data.access_token;
const profileResponse = await axios.get("https://api.linkedin.com/v2/me", {
headers: { Authorization: `Bearer ${accessToken}` }
});
const emailResponse = await axios.get("https://api.linkedin.com/v2/emailAddress?q=members&projection=(elements*(handle~))", {
headers: { Authorization: `Bearer ${accessToken}` }
});
res.json({
profile: profileResponse.data,
email: emailResponse.data
});
});
app.listen(3000, () => console.log("Server running on http://localhost:3000"));
LinkedIn Login Button Flow in Angular
Once you’ve set up your LinkedIn app and backend API, you can integrate the login flow directly into your Angular frontend. Here’s how:
Step 1: Create an Auth Service
This service will handle building the authorization URL and redirecting users to LinkedIn.
// src/app/services/linkedin-auth.service.ts
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class LinkedinAuthService {
private clientId = 'YOUR_LINKEDIN_CLIENT_ID';
private redirectUri = 'http://localhost:4200/auth/callback'; // must match LinkedIn app config
private scope = 'r_liteprofile r_emailaddress';
constructor() {}
loginWithLinkedIn(): void {
const authUrl = `https://www.linkedin.com/oauth/v2/authorization?response_type=code&client_id=${this.clientId}&redirect_uri=${encodeURIComponent(this.redirectUri)}&scope=${encodeURIComponent(this.scope)}`;
window.location.href = authUrl;
}
}
Step 2: Create a Login Component
// src/app/components/login/login.component.ts
import { Component } from '@angular/core';
import { LinkedinAuthService } from '../../services/linkedin-auth.service';
@Component({
selector: 'app-login',
template: `
<button (click)="login()">Login with LinkedIn</button>
`,
styles: [`
button {
background-color: #0077B5;
color: white;
border: none;
padding: 10px 20px;
font-size: 16px;
cursor: pointer;
border-radius: 4px;
}
button:hover {
background-color: #005582;
}
`]
})
export class LoginComponent {
constructor(private linkedinAuth: LinkedinAuthService) {}
login(): void {
this.linkedinAuth.loginWithLinkedIn();
}
}
Step 3: Handle Callback Route
Create a callback component to capture the code returned by LinkedIn.
// src/app/components/auth-callback/auth-callback.component.ts
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { HttpClient } from '@angular/common/http';
@Component({
selector: 'app-auth-callback',
template: `<p>Processing LinkedIn login...</p>`
})
export class AuthCallbackComponent implements OnInit {
constructor(private route: ActivatedRoute, private http: HttpClient) {}
ngOnInit(): void {
this.route.queryParams.subscribe(params => {
const code = params['code'];
if (code) {
// Send code to backend to exchange for access token
this.http.post('http://localhost:3000/auth/linkedin', { code })
.subscribe({
next: (response) => console.log('User info:', response),
error: (err) => console.error('Login failed:', err)
});
}
});
}
}
Step 4: Update Angular Routing
// src/app/app-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { LoginComponent } from './components/login/login.component';
import { AuthCallbackComponent } from './components/auth-callback/auth-callback.component';
const routes: Routes = [
{ path: '', component: LoginComponent },
{ path: 'auth/callback', component: AuthCallbackComponent }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule {}
Step 5: Backend Endpoint (for Token Exchange)
Your Angular app should not directly call LinkedIn with the client secret. Instead, send the code to your backend API:
// Example Express endpoint
app.post("/auth/linkedin", async (req, res) => {
const { code } = req.body;
const tokenResponse = await axios.post("https://www.linkedin.com/oauth/v2/accessToken", null, {
params: {
grant_type: "authorization_code",
code: code,
redirect_uri: "http://localhost:4200/auth/callback",
client_id: process.env.LINKEDIN_CLIENT_ID,
client_secret: process.env.LINKEDIN_CLIENT_SECRET
}
});
const accessToken = tokenResponse.data.access_token;
const profileResponse = await axios.get("https://api.linkedin.com/v2/me", {
headers: { Authorization: `Bearer ${accessToken}` }
});
const emailResponse = await axios.get("https://api.linkedin.com/v2/emailAddress?q=members&projection=(elements*(handle~))", {
headers: { Authorization: `Bearer ${accessToken}` }
});
res.json({
profile: profileResponse.data,
email: emailResponse.data
});
});
Final Flow
- User clicks Login with LinkedIn button.
- Angular service redirects them to LinkedIn’s login screen.
- LinkedIn redirects back with a
code → Angular captures it.
- Angular sends
code to your backend.
- Backend exchanges code for an access token and fetches user details.
- Backend responds with profile + email → Angular stores user session.
This approach keeps your client secret secure while providing a smooth LinkedIn login flow.
Conclusion
Integrating the LinkedIn API into your web app allows you to:
- Simplify user onboarding with LinkedIn login
- Fetch user profile and email details
- Enhance your app with professional data
With OAuth 2.0, LinkedIn ensures secure access, and the API makes it straightforward to fetch meaningful user information.