passport-facebook, passport-github, passport-google-oauth20, and passport-twitter are authentication strategies for the Passport.js middleware in Node.js applications. Each implements a specific OAuth flow to allow users to log in using their accounts from Facebook, GitHub, Google, or Twitter. These packages abstract the protocol details—such as token exchange, profile fetching, and signature validation—so developers can integrate social login without managing low-level HTTP requests or cryptographic operations.
When adding social login to a Node.js app using Passport.js, choosing the right strategy matters—not just for code structure, but for reliability, user trust, and long-term maintenance. All four packages (passport-facebook, passport-github, passport-google-oauth20, passport-twitter) plug into Passport’s standard interface, but they differ significantly in protocol, data access, and real-world viability. Let’s break down what you need to know.
Three of these strategies use OAuth 2.0, which relies on HTTPS and bearer tokens. One—Twitter—still uses OAuth 1.0a, which requires cryptographic signing of every request.
passport-facebook, passport-github, and passport-google-oauth20 all follow the same OAuth 2.0 pattern:
// Generic OAuth 2.0 setup (applies to Facebook, GitHub, Google)
const Strategy = require('passport-facebook').Strategy; // or -github, -google-oauth20
passport.use(new Strategy({
clientID: process.env.CLIENT_ID,
clientSecret: process.env.CLIENT_SECRET,
callbackURL: "/auth/facebook/callback" // or /github, /google
}, (accessToken, refreshToken, profile, done) => {
// Use profile info to find or create user
return done(null, profile);
}));
passport-twitter uses OAuth 1.0a, which requires no redirect URI in the initial request and involves a three-legged handshake with request tokens:
// Twitter uses OAuth 1.0a
const TwitterStrategy = require('passport-twitter').Strategy;
passport.use(new TwitterStrategy({
consumerKey: process.env.TWITTER_CONSUMER_KEY,
consumerSecret: process.env.TWITTER_CONSUMER_SECRET,
callbackURL: "/auth/twitter/callback"
}, (token, tokenSecret, profile, done) => {
return done(null, profile);
}));
💡 Why it matters: OAuth 2.0 is simpler to implement and debug. OAuth 1.0a adds complexity because every request must be signed—something
passport-twitterhandles internally, but errors are harder to troubleshoot.
Each provider returns a normalized profile object, but the actual fields and reliability vary.
Facebook (via passport-facebook) returns:
{
id: '123456789',
displayName: 'Jane Doe',
emails: [{ value: 'jane@example.com' }],
photos: [{ value: 'https://graph.facebook.com/.../picture' }]
}
But note: since 2018, Facebook requires app review to access most fields beyond basic profile and email.
GitHub (via passport-github) gives:
{
id: 12345,
username: 'janedoe',
displayName: 'Jane Doe',
emails: [{ value: 'jane@users.noreply.github.com', verified: true }]
}
You’ll need the user:email scope to see private emails.
Google (via passport-google-oauth20) provides:
{
id: '123456789012345678901',
displayName: 'Jane Doe',
emails: [{ value: 'jane@gmail.com', verified: true }],
photos: [{ value: 'https://lh3.googleusercontent.com/...' }]
}
Google’s data is consistent and includes verified email by default with the email scope.
Twitter (via passport-twitter) returns:
{
id: 123456789,
username: 'janedoe',
displayName: 'Jane Doe',
photos: [{ value: 'https://pbs.twimg.com/profile_images/...' }]
}
But no email by default—unless you explicitly request it and your app is approved by Twitter, which is now extremely difficult.
⚠️ Critical note: As of 2023, Twitter’s API changes mean many apps can no longer retrieve user emails or even basic profile data reliably. Avoid
passport-twitterfor new projects.
All strategies require registering an app with the provider, but setup effort differs.
Example route setup (same for all):
// Initiate auth
app.get('/auth/google', passport.authenticate('google', { scope: ['profile', 'email'] }));
// Callback
app.get('/auth/google/callback',
passport.authenticate('google', { failureRedirect: '/login' }),
(req, res) => res.redirect('/')
);
The only difference is the strategy name and required scopes.
passport-google-oauth20: Actively maintained. Google’s OAuth system is stable and enterprise-grade.passport-github: Actively maintained. GitHub’s API is developer-friendly and unlikely to change drastically.passport-facebook: Actively maintained, but Facebook’s permission model makes it less useful unless you’re willing to go through app review.passport-twitter: Not officially deprecated, but effectively unusable for most new apps due to Twitter’s API restrictions and lack of email access. Do not choose this unless you have a legacy integration or special approval.| Use Case | Recommended Strategy |
|---|---|
| General consumer app with broad user base | passport-google-oauth20 (highest trust, verified email) |
| Developer tool or internal dashboard | passport-github (natural fit, easy setup) |
| App targeting Facebook users (e.g., social games) | passport-facebook (but expect limited data) |
| New project requiring Twitter login | Avoid — use email/password or another provider instead |
Stick with Google or GitHub for most new applications—they offer reliable identity data, simple OAuth 2.0 flows, and stable APIs. Facebook is viable if you accept its data limitations. Twitter should be avoided entirely for new development due to platform instability and access restrictions. Always test the full auth flow in a staging environment, and never assume email will be available—handle missing emails gracefully in your user model.
Choose passport-facebook when your application needs to support Facebook Login. It implements OAuth 2.0 and requires a Facebook App ID and secret. Be aware that Facebook’s Graph API permissions have tightened over time, so you may only get basic profile data (name, email, ID) unless your app undergoes review. This package is actively maintained and suitable for new projects.
Choose passport-github if you want users to authenticate with their GitHub accounts—common in developer tools or internal dashboards. It uses OAuth 2.0 and supports scopes like user:email to access private emails. GitHub’s API is stable and well-documented, making this strategy reliable for both public and private profile access. The package is actively maintained and works well in modern apps.
Choose passport-google-oauth20 for Google Sign-In, which is widely trusted by users and provides robust identity verification. It strictly follows OAuth 2.0 and supports configurable scopes (e.g., profile, email, openid). Google’s identity platform is enterprise-ready and integrates smoothly with Firebase or G Suite. This package is the official and recommended way to use Google OAuth with Passport and is actively maintained.
Choose passport-twitter only if you specifically need Twitter login and understand that it uses OAuth 1.0a—a more complex protocol involving request signing—rather than OAuth 2.0. Note that as of April 2023, Twitter deprecated API v1.1 and restricted access under Elon Musk’s ownership, making user authentication unreliable for new apps. While the package itself isn’t marked deprecated, real-world usability is limited due to Twitter’s policy changes, so avoid it for new projects.
Passport strategy for authenticating with Facebook using the OAuth 2.0 API.
This module lets you authenticate using Facebook in your Node.js applications. By plugging into Passport, Facebook authentication can be easily and unobtrusively integrated into any application or framework that supports Connect-style middleware, including Express.
1Password, the only password manager you should trust. Industry-leading security and award winning design.
$ npm install passport-facebook
Before using passport-facebook, you must register an application with
Facebook. If you have not already done so, a new application can be created at
Facebook Developers. Your application will
be issued an app ID and app secret, which need to be provided to the strategy.
You will also need to configure a redirect URI which matches the route in your
application.
The Facebook authentication strategy authenticates users using a Facebook
account and OAuth 2.0 tokens. The app ID and secret obtained when creating an
application are supplied as options when creating the strategy. The strategy
also requires a verify callback, which receives the access token and optional
refresh token, as well as profile which contains the authenticated user's
Facebook profile. The verify callback must call cb providing a user to
complete authentication.
passport.use(new FacebookStrategy({
clientID: FACEBOOK_APP_ID,
clientSecret: FACEBOOK_APP_SECRET,
callbackURL: "http://localhost:3000/auth/facebook/callback"
},
function(accessToken, refreshToken, profile, cb) {
User.findOrCreate({ facebookId: profile.id }, function (err, user) {
return cb(err, user);
});
}
));
Use passport.authenticate(), specifying the 'facebook' strategy, to
authenticate requests.
For example, as route middleware in an Express application:
app.get('/auth/facebook',
passport.authenticate('facebook'));
app.get('/auth/facebook/callback',
passport.authenticate('facebook', { failureRedirect: '/login' }),
function(req, res) {
// Successful authentication, redirect home.
res.redirect('/');
});
Developers using the popular Express web framework can refer to an example as a starting point for their own web applications.
If you need additional permissions from the user, the permissions can be
requested via the scope option to passport.authenticate().
app.get('/auth/facebook',
passport.authenticate('facebook', { scope: ['user_friends', 'manage_pages'] }));
Refer to permissions with Facebook Login for further details.
Set the authType option to reauthenticate when authenticating.
app.get('/auth/facebook',
passport.authenticate('facebook', { authType: 'reauthenticate', scope: ['user_friends', 'manage_pages'] }));
Refer to re-asking for declined permissions for further details.
The Facebook profile contains a lot of information about a user. By default,
not all the fields in a profile are returned. The fields needed by an application
can be indicated by setting the profileFields option.
new FacebookStrategy({
clientID: FACEBOOK_APP_ID,
clientSecret: FACEBOOK_APP_SECRET,
callbackURL: "http://localhost:3000/auth/facebook/callback",
profileFields: ['id', 'displayName', 'photos', 'email']
}), ...)
Refer to the User section of the Graph API Reference for the complete set of available fields.
Set the enableProof option when creating the strategy.
new FacebookStrategy({
clientID: FACEBOOK_APP_ID,
clientSecret: FACEBOOK_APP_SECRET,
callbackURL: "http://localhost:3000/auth/facebook/callback",
enableProof: true
}, ...)
As detailed in securing graph API requests, requiring the app secret for server API requests helps prevent use of tokens stolen by malicous software or man in the middle attacks.
This behavior is "by design" according to Facebook's response to a bug filed regarding this issue.
Fragment identifiers are not supplied in requests made to a server, and as such this strategy is not aware that this behavior is exhibited and is not affected by it. If desired, this fragment can be removed on the client side. Refer to this discussion on Stack Overflow for recommendations on how to accomplish such removal.
Passport is open source software. Ongoing development is made possible by generous contributions from individuals and corporations. To learn more about how you can help keep this project financially sustainable, please visit Jared Hanson's page on Patreon.
Copyright (c) 2011-2016 Jared Hanson <http://jaredhanson.net/>