Basic Node.js User Authentication Guide
User authentication is a critical feature for any application where user data and personalized experiences are involved. In this blog, we’ll dive into the fundamentals of setting up user authentication in a Node.js environment using libraries such as Express, Passport.js, and bcrypt for securing passwords.
1. Setting Up the Project
Start by creating a new Node.js project and installing necessary packages:
bashCopy codemkdir auth-demo
cd auth-demo
npm init -y
npm install express passport passport-local bcryptjs express-session
2. Configuring the Server and Middleware
Set up an Express server and configure middleware to handle sessions and parsing:
javascriptCopy codeconst express = require('express');
const session = require('express-session');
const passport = require('passport');
const app = express();
app.use(express.urlencoded({ extended: false }));
app.use(session({
secret: 'your_secret_key',
resave: false,
saveUninitialized: true
}));
app.use(passport.initialize());
app.use(passport.session());
3. Setting Up Passport for Authentication
Define a local authentication strategy using Passport.js. Here, Passport will compare the provided credentials with stored user data. For a simple demo, a mock user object can be used, but in production, you’ll query a database.
javascriptCopy codeconst LocalStrategy = require('passport-local').Strategy;
const bcrypt = require('bcryptjs');
// Mock user data
const users = [{ id: 1, username: 'user', password: '$2a$10$...' }];
passport.use(new LocalStrategy((username, password, done) => {
const user = users.find(u => u.username === username);
if (!user) return done(null, false, { message: 'Incorrect username' });
bcrypt.compare(password, user.password, (err, isMatch) => {
if (err) return done(err);
if (isMatch) return done(null, user);
return done(null, false, { message: 'Incorrect password' });
});
}));
passport.serializeUser((user, done) => done(null, user.id));
passport.deserializeUser((id, done) => {
const user = users.find(u => u.id === id);
done(null, user);
});
4. Building Routes for Login and Registration
Set up routes for handling registration, login, and logout. Here’s a simple setup:
javascriptCopy codeapp.post('/login', passport.authenticate('local', {
successRedirect: '/dashboard',
failureRedirect: '/login',
failureFlash: true
}));
app.post('/register', async (req, res) => {
const { username, password } = req.body;
const hashedPassword = await bcrypt.hash(password, 10);
users.push({ id: Date.now(), username, password: hashedPassword });
res.redirect('/login');
});
app.get('/logout', (req, res) => {
req.logout(err => {
if (err) return next(err);
res.redirect('/');
});
});
5. Securing Routes with Middleware
Add middleware to protect routes accessible only to authenticated users:
javascriptCopy codefunction isAuthenticated(req, res, next) {
if (req.isAuthenticated()) return next();
res.redirect('/login');
}
app.get('/dashboard', isAuthenticated, (req, res) => {
res.send('Welcome to your dashboard!');
});
6. Testing and Expanding
Start the server and test the routes. As a next step, consider integrating with a database like MongoDB to manage user accounts or adding two-factor authentication for added security.
Conclusion
This guide covers a basic implementation of user authentication in Node.js using Passport.js and bcrypt for hashing. It’s an essential foundation that you can expand on with more advanced features, such as email verification, OAuth integration, and secure session handling for a robust authentication solution.