These packages are authentication strategies for Passport.js, a widely used authentication middleware for Node.js applications. They enable developers to integrate login functionality using external identity providers like Auth0, Google, and LinkedIn. While passport-google-oauth20, passport-auth0, and passport-linkedin-oauth2 are pre-configured strategies for specific providers, passport-oauth2 serves as the base class for implementing custom OAuth2 flows. Frontend architects should note that these libraries run on the server side, requiring a Node.js backend or Backend-for-Frontend (BFF) pattern to manage sessions securely.
Integrating social login or enterprise identity into a Node.js application usually involves Passport.js. The packages passport-auth0, passport-google-oauth20, passport-linkedin-oauth2, and passport-oauth2 all solve the same core problem — allowing users to log in via external providers — but they differ in setup, maintenance, and flexibility. Let’s compare how they handle real-world engineering scenarios.
passport-auth0 is designed for the Auth0 platform.
// passport-auth0: Configured for Auth0 tenant
const Auth0Strategy = require('passport-auth0').Strategy;
passport.use(new Auth0Strategy({
domain: process.env.AUTH0_DOMAIN,
clientID: process.env.AUTH0_CLIENT_ID,
clientSecret: process.env.AUTH0_CLIENT_SECRET,
callbackURL: process.env.AUTH0_CALLBACK_URL
},
verifyCallback
));
passport-google-oauth20 is optimized for Google Identity.
// passport-google-oauth20: Configured for Google
const GoogleStrategy = require('passport-google-oauth20').Strategy;
passport.use(new GoogleStrategy({
clientID: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
callbackURL: "/auth/google/callback"
},
verifyCallback
));
passport-linkedin-oauth2 targets LinkedIn Sign-In.
// passport-linkedin-oauth2: Configured for LinkedIn
const LinkedInStrategy = require('passport-linkedin-oauth2').Strategy;
passport.use(new LinkedInStrategy({
clientID: process.env.LINKEDIN_CLIENT_ID,
clientSecret: process.env.LINKEDIN_CLIENT_SECRET,
callbackURL: "/auth/linkedin/callback",
scope: ['r_liteprofile', 'r_emailaddress']
},
verifyCallback
));
passport-oauth2 is the generic base class.
// passport-oauth2: Generic configuration
const OAuth2Strategy = require('passport-oauth2').Strategy;
passport.use(new OAuth2Strategy({
authorizationURL: 'https://provider.com/oauth/authorize',
tokenURL: 'https://provider.com/oauth/token',
clientID: process.env.CLIENT_ID,
clientSecret: process.env.CLIENT_SECRET,
callbackURL: "/auth/callback"
},
verifyCallback
));
How each package returns user data varies significantly. This affects how you map external identities to your internal user database.
passport-auth0 returns a normalized profile.
// passport-auth0: Normalized profile
function verifyCallback(accessToken, refreshToken, profile, done) {
// profile.id, profile.displayName, profile.emails are standard
User.findOrCreate({ auth0Id: profile.id }, (err, user) => done(err, user));
}
passport-google-oauth20 returns Google-specific data.
// passport-google-oauth20: Google profile shape
function verifyCallback(accessToken, refreshToken, profile, done) {
// profile.emails is an array
const email = profile.emails[0].value;
User.findOrCreate({ googleId: profile.id }, (err, user) => done(err, user));
}
passport-linkedin-oauth2 returns LinkedIn-specific data.
// passport-linkedin-oauth2: LinkedIn profile shape
function verifyCallback(accessToken, refreshToken, profile, done) {
// profile.emails might be structured differently based on API version
User.findOrCreate({ linkedInId: profile.id }, (err, user) => done(err, user));
}
passport-oauth2 returns raw provider data.
// passport-oauth2: Raw profile handling
function verifyCallback(accessToken, refreshToken, profile, done) {
// profile is often just { id: ... } or requires extra API call
// You must fetch user details manually if not provided
User.findOrCreate({ providerId: profile.id }, (err, user) => done(err, user));
}
Provider APIs change over time. This impacts how much work your team must do to keep login working.
passport-auth0 is managed by Auth0.
// passport-auth0: Updates handled via npm
// npm install passport-auth0@latest
// Configuration remains stable unless Auth0 changes tenants
passport-google-oauth20 is highly stable.
// passport-google-oauth20: Long-term support
// npm install passport-google-oauth20@latest
// Rarely requires code changes
passport-linkedin-oauth2 requires vigilance.
// passport-linkedin-oauth2: Check for API deprecation
// npm install passport-linkedin-oauth2@latest
// Monitor LinkedIn developer changelog for breaking changes
passport-oauth2 depends on your provider.
// passport-oauth2: Manual endpoint monitoring
// npm install passport-oauth2@latest
// You must update authorizationURL and tokenURL if provider changes them
Frontend architects must remember these libraries run on the server. They cannot be used directly in browser-only React or Vue apps without a backend layer.
passport-auth0 supports enterprise federation.
// passport-auth0: Server-side session
app.get('/dashboard', ensureAuthenticated, (req, res) => {
res.render('dashboard', { user: req.user });
});
passport-google-oauth20 is common for B2C apps.
// passport-google-oauth20: Server-side session
app.get('/dashboard', ensureAuthenticated, (req, res) => {
res.render('dashboard', { user: req.user });
});
passport-linkedin-oauth2 suits professional tools.
// passport-linkedin-oauth2: Server-side session
app.get('/dashboard', ensureAuthenticated, (req, res) => {
res.render('dashboard', { user: req.user });
});
passport-oauth2 fits custom enterprise needs.
// passport-oauth2: Server-side session
app.get('/dashboard', ensureAuthenticated, (req, res) => {
res.render('dashboard', { user: req.user });
});
| Feature | passport-auth0 | passport-google-oauth20 | passport-linkedin-oauth2 | passport-oauth2 |
|---|---|---|---|---|
| Provider | Auth0 Platform | Any OAuth2 Provider | ||
| Setup Effort | Low | Low | Medium | High |
| Maintenance | Low (Managed) | Low (Stable) | Medium (API Changes) | High (Manual) |
| Profile Data | Normalized | Google Standard | LinkedIn Standard | Raw/Custom |
| Best Use | Enterprise/SSO | Consumer Apps | Professional Networks | Custom/Internal IDP |
passport-google-oauth20 is the default choice for consumer-facing apps. It is reliable, well-maintained, and users trust Google login. Use this unless you have a specific reason not to.
passport-auth0 is the best choice for teams wanting a full identity platform. It handles more than just login — including rules, databases, and enterprise connections. Ideal for startups scaling quickly or enterprises needing SSO.
passport-linkedin-oauth2 is a niche choice. Use it only if your app value depends on professional data. Be prepared to monitor API changes closely.
passport-oauth2 is the fallback and power-user tool. Use it when no specific strategy exists or when you need to integrate with a custom identity provider. It requires more code but offers total control.
Final Thought: All four packages require a Node.js backend to handle secrets and sessions securely. Frontend teams should plan for a Backend-for-Frontend (BFF) layer if their architecture is currently serverless or static-only. Choose the strategy that matches your identity provider — not just the one with the easiest setup.
Choose passport-auth0 if your organization already uses Auth0 for identity management. It simplifies configuration by handling Auth0-specific endpoints and OIDC compliance automatically. This is ideal for teams wanting a managed identity solution without maintaining user databases.
Choose passport-google-oauth20 for applications targeting consumers who commonly use Google accounts. It is highly stable, maintained by the creator of Passport, and requires minimal setup for standard Google login flows.
Choose passport-linkedin-oauth2 only if professional networking data is critical to your app. Be aware that LinkedIn changes their API frequently, so this strategy may require more maintenance than others. Verify the specific fork you use supports the latest LinkedIn API version.
Choose passport-oauth2 when no official strategy exists for your identity provider or when you need full control over the OAuth2 flow. It requires manual configuration of authorization and token URLs but offers maximum flexibility for custom or enterprise identity systems.

The Auth0 authentication strategy for Passport.js, an authentication middleware for Node.js that can be unobtrusively dropped into any Express-based web application.
:books: Documentation - :rocket: Getting Started - :speech_balloon: Feedback
:information_source: Maintenance Advisory: With the release of https://github.com/auth0/express-openid-connect, we will no longer be adding new features to this library, however we will continue to maintain this library and fix issues. You can read more about the release of our new library at https://auth0.com/blog/auth0-s-express-openid-connect-sdk/
The Auth0 Passport strategy is installed with npm.
npm install passport-auth0
The Auth0 Passport strategy enforces the use of the state parameter in OAuth 2.0 authorization requests and requires session support in Express to be enabled.
If you require the state parameter to be omitted (which is not recommended), you can suppress it when calling the Auth0 Passport strategy constructor:
const Auth0Strategy = require('passport-auth0');
const strategy = new Auth0Strategy({
// ...
state: false
},
function(accessToken, refreshToken, extraParams, profile, done) {
// ...
}
);
If you want to change the scope of the ID token provided, add a scope property to the authenticate configuration passed when defining the route. These must be OIDC standard scopes. If you need data outside of the standard scopes, you can add custom claims to the token.
app.get(
'/login',
passport.authenticate('auth0', {scope: 'openid email profile'}),
function (req, res) {
res.redirect('/');
}
);
If you want to force a specific identity provider you can use:
app.get(
'/login/google',
passport.authenticate('auth0', {connection: 'google-oauth2'}),
function (req, res) {
res.redirect('/');
}
);
If you force an identity provider you can also request custom scope from that identity provider:
app.get(
'/login/google',
passport.authenticate('auth0', {
connection: 'google-oauth2',
connection_scope: 'https://www.googleapis.com/auth/analytics, https://www.googleapis.com/auth/contacts.readonly'
}),
function (req, res) {
res.redirect('/');
}
);
If you want to specify an audience for the returned access_token you can:
app.get(
'/login',
passport.authenticate('auth0', {audience: 'urn:my-api'}),
function (req, res) {
res.redirect('/');
}
);
If you want to check authentication without showing a prompt:
app.get(
'/login',
passport.authenticate('auth0', {prompt: 'none'}),
function (req, res) {
res.redirect('/');
}
);
We appreciate feedback and contribution to this repo! Before you get started, please see the following:
To provide feedback or report a bug, please raise an issue on our issue tracker.
Please do not report security vulnerabilities on the public GitHub issue tracker. The Responsible Disclosure Program details the procedure for disclosing security issues.
Auth0 is an easy to implement, adaptable authentication and authorization platform. To learn more checkout Why Auth0?
This project is licensed under the MIT license. See the LICENSE file for more info.