@authial/linkedin
v1.1.0
Published
LinkedIn OAuth 2.0 authentication strategy for Passport with TypeScript support.
Maintainers
Readme
LinkedIn OAuth 2.0 authentication strategy for Passport with TypeScript support
Authenticates users via LinkedIn’s 3-legged OAuth 2.0 flow, handling the authorization process and retrieval of user profile information.
Important notes
- LinkedIn access tokens are typically valid for 60 days for non-MDP (Marketing Developer Platform) partners.
- Refresh tokens are not provided unless your app is approved as an MDP partner.
- You should calculate token expiration as
current_date + 60 daysand store it in your database. - When tokens expire, users must re-authenticate through the same OAuth flow.
Required options
clientID– Your LinkedIn application’s Client ID (from the LinkedIn Developer Portal).clientSecret– Your LinkedIn application’s Client Secret (keep this secure).callbackURL– The URL LinkedIn redirects to after user authorization.
Optional configuration
scope– Array of permissions (default:['openid', 'profile', 'email']).state– Enable CSRF protection (recommended:true).userProfileURL– Custom profile endpoint (default: LinkedIn’s v2 userinfo).
Usage
Before using this application, you must first set up an app on LinkedIn Developer Portal. Here’s a step-by-step guide:
Create a LinkedIn App:
- Visit the LinkedIn Developer Portal.
- Sign in with your LinkedIn account.
- Click on "Create app" and fill in the required details such as your app's name, description, and logo.
Get Your Client ID and Client Secret:
- Once your app is created, you’ll find your Client ID and Client Secret in the app settings. Keep these credentials secure.
Set Up Required Scopes:
- In your app settings, navigate to the "Auth" tab.
- Under the "OAuth 2.0 settings," you will find a list of available scopes. Choose the scopes as per your application's requirements and add the Redirect URI that will handle JSON responses from LinkedIn.
- Default scopes such as
openid,profile, andemailare already included when you set up your app.
Authentication:
- Use the obtained Client ID and Client Secret in your application to authenticate users and access LinkedIn data as per the configured scopes.
Make sure you handle the authentication flow correctly in your application to ensure users can sign in and authorize access appropriately.
Example: basic usage with token expiration
import passport from 'passport';
import { Strategy as LinkedInStrategy } from '@authial/passport-linkedin';
passport.use(
new LinkedInStrategy(
{
clientID: process.env.LINKEDIN_CLIENT_ID!,
clientSecret: process.env.LINKEDIN_CLIENT_SECRET!,
callbackURL: 'https://yourapp.com/auth/linkedin/callback',
scope: ['openid', 'profile', 'email', 'w_member_social'],
state: true, // Enable CSRF protection
},
async (accessToken, refreshToken, profile, done) => {
try {
// Calculate token expiration (60 days from now for non-MDP partners)
const tokenExpiresAt = new Date();
tokenExpiresAt.setDate(tokenExpiresAt.getDate() + 60);
// Save user and token info to your database
const user = await db.user.upsert({
where: { linkedinId: profile.id },
update: {
accessToken,
tokenExpiresAt, // Store when token expires
email: profile.emails?.value,
displayName: profile.displayName,
},
create: {
linkedinId: profile.id,
accessToken,
tokenExpiresAt,
email: profile.emails?.value,
displayName: profile.displayName,
},
});
// Note: refreshToken will be undefined for non-MDP partners
return done(null, user);
} catch (error) {
return done(error);
}
},
),
);Example: middleware to handle token expiration
// Middleware to check if LinkedIn token is still valid
async function validateLinkedInToken(req, res, next) {
const user = await db.user.findUnique({ where: { id: req.user.id } });
if (!user?.accessToken || Date.now() >= user.tokenExpiresAt.getTime()) {
// Token expired - redirect or instruct client to re-auth
return res.status(401).json({
error: 'LinkedIn token expired',
message: 'Please re-authorize with LinkedIn',
redirectUrl: '/auth/linkedin', // Same OAuth flow
});
}
req.user.accessToken = user.accessToken;
next();
}
// Use in protected routes
app.get('/api/linkedin/profile', validateLinkedInToken, async (req, res) => {
// Make LinkedIn API calls with a valid token
});Authors
References
- LinkedIn OAuth 2.0 Authorization Code Flow: https://learn.microsoft.com/en-us/linkedin/shared/authentication/authorization-code-flow
- LinkedIn Developer Portal: https://developer.linkedin.com
