If you're diving into web development, chances are you'll encounter Passport.js, a powerful authentication middleware for Node.js applications. This guide will break down Passport.js into three key components: strategy, middleware, and session handling.
Passport Strategy
What is a Strategy?
Think of a strategy as the answer to the question, "How do you log in and identify the user?" It contains two main parts: the configuration and the handler function.
Configuration:
- Settings to connect with an external API, if needed.
- Not every strategy requires configuration.
// Example LocalStrategy configuration
const LocalStrategy = require('passport-local').Strategy;
passport.use(new LocalStrategy(
(username, password, done) => {
// Validate user credentials and return the local user
// ...
}
));
Handler Function:
- Executed after a successful login for the specific strategy.
- Takes the login process payload and returns the local user.
- For example, FacebookStrategy deals with tokens and user profiles.
// Example FacebookStrategy handler function
passport.use(new FacebookStrategy(
{
clientID: 'your-client-id',
clientSecret: 'your-client-secret',
callbackURL: 'your-callback-url',
},
(accessToken, refreshToken, profile, done) => {
// Upsert the user in the database based on the Facebook profile
// ...
return done(null, user);
}
));
Pro Tip: Your app can use multiple strategies, such as local usernames/passwords, "Login with Facebook," or "Login with Google."
Middleware
What is Middleware?
Middleware is where you apply authentication to your user's experience, consisting of setup, the login flow, and checking if the user is logged in.
Setup:
- Initialize and use Passport in your app.
-
passport.initialize()
creates the passport object on the request. -
passport.session()
sets up serialize and deserialize methods.
// Setup Passport middleware
app.use(passport.initialize());
app.use(passport.session());
Login Flow:
- Set up a login URL for each strategy.
- Use
passport.authenticate('something')
for the internal strategy name. - Strategies may have a callback endpoint for handling authentication flow.
// Example login flow for LocalStrategy
app.post('/login',
passport.authenticate('local', { failureRedirect: '/login' }),
(req, res) => {
res.redirect('/');
}
);
isAuthenticated:
- Custom middleware to check if a user is logged in.
- Protect endpoints by ensuring they are authenticated.
// Custom middleware to check if a user is authenticated
function isAuthenticated(req, res, next) {
if (req.isAuthenticated()) {
return next();
}
res.redirect('/login');
}
// Protect an endpoint using isAuthenticated middleware
app.get('/protected', isAuthenticated, (req, res) => {
res.send('This is a protected endpoint');
});
Session Handling
What is Session Handling?
Handles user sessions, ensuring they stay logged in across requests.
deserializeUser
:
- Called during passport.session().
- Takes a session token (from serializeUser) and returns the local user or false.
// Example deserializeUser method
passport.deserializeUser((id, done) => {
// Fetch the user from the database based on the user ID
// ...
done(null, user);
});
serializeUser
:
- Called after the Strategy handler.
- It takes the local user and returns a string stored in the session.
- The string is used in deserializeUser to identify the user in your database.
// Example serializeUser method
passport.serializeUser((user, done) => {
// Store the user ID in the session
done(null, user.id);
});
By understanding these three components, you'll be well-equipped to implement secure authentication in your Node.js applications using Passport.js. Remember to explore the various strategies available to suit your specific authentication needs.
Top comments (0)