A Quick Guide to Getting LinkedIn OAuth Working Correctly
LinkedIn authentication is a powerful feature to add to your Next.js application using NextAuth.js, but the default configuration can often lead to issues — especially when trying to fetch user details like email, name, and profile picture.
In this article, I’ll walk you through how I solved this issue by customizing the LinkedIn provider configuration in NextAuth.js.
🧪 The Problem
Using the default LinkedInProvider
setup from next-auth/providers/linkedin
may not always return complete user information such as email or profile picture.
🔧 Default Implementation
import LinkedInProvider from "next-auth/providers/linkedin";
providers: [
LinkedInProvider({
clientId: process.env.LINKEDIN_CLIENT_ID,
clientSecret: process.env.LINKEDIN_CLIENT_SECRET,
})
]
This basic setup often results in incomplete data being returned from LinkedIn.
✅ The Fix
To overcome this, I had to dig into LinkedIn’s OAuth docs and customize the LinkedInProvider
to manually specify scopes, endpoints, and userinfo configurations.
💡 Working LinkedInProvider Configuration
LinkedInProvider({
clientId: process.env.LINKEDIN_CLIENT_ID ?? "",
clientSecret: process.env.LINKEDIN_CLIENT_SECRET ?? "",
client: { token_endpoint_auth_method: "client_secret_post" },
scope: "r_liteprofile r_emailaddress",
issuer: "https://www.linkedin.com",
userinfo: {
url: "https://api.linkedin.com/v2/userinfo",
},
token: {
url: "https://www.linkedin.com/oauth/v2/accessToken",
},
wellKnown: "https://www.linkedin.com/oauth/.well-known/openid-configuration",
authorization: {
url: "https://www.linkedin.com/oauth/v2/authorization",
params: {
scope: "profile email openid",
prompt: "consent",
access_type: "offline",
response_type: "code",
},
},
jwks_endpoint: "https://www.linkedin.com/oauth/openid/jwks",
async profile(profile) {
return {
id: profile.sub,
name: profile.name,
firstname: profile.given_name,
lastname: profile.family_name,
email: profile.email,
image: profile.picture,
};
},
}),
This configuration ensures you:
- Request proper scopes like
r_emailaddress
- Use the correct LinkedIn OAuth endpoints
- Get a complete
profile
object including email and picture
🔐 Bonus Tip: Twitter Provider Email Issue
If you're using Twitter authentication as well, make sure you enable email access in your Twitter app settings. Without this, you won’t get the user’s email address.
TwitterProvider({
clientId: process.env.TWITTER_CLIENT_ID,
clientSecret: process.env.TWITTER_CLIENT_SECRET,
})
✅ Tip: Enable "Request email address from users" in Twitter Developer Portal.
🧵 TL;DR
- Default
LinkedInProvider
doesn’t return complete user info. - Customize it with the right OAuth config to fix it.
- Twitter requires email permission to return user emails.
Thanks for reading! 🚀
If you found this helpful, consider following me on Twitter and checking out my other projects like Resume Builder.
Let me know if you’ve faced similar issues or need help with OAuth in your apps! 💬
Top comments (3)
That fix is clutch.
Man, getting LinkedIn auth solid was such a headache for me too - super grateful someone actually spelled this out.
Very helpful, thanks! 🙏