Implementing authentication in an Express.js application can be streamlined using Passport.js, a flexible and modular middleware. This guide provides a step-by-step process to set up and configure Passport.js for user authentication.

Prerequisites

  • Node.js and npm installed
  • Basic knowledge of Express.js
  • Understanding of middleware concepts
  • A new or existing Express project

Step 1: Install Required Packages

  • passport
  • passport-local
  • express-session
  • bcryptjs (for password hashing)

Run the following command in your project directory:

npm install passport passport-local express-session bcryptjs

Step 2: Configure Express and Middleware

Set up your Express server with session management and initialize Passport:

const 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: false }));
app.use(passport.initialize());
app.use(passport.session());

Step 3: Define User Data and Authentication Logic

For demonstration, use a simple user array. In production, connect to a database.

const users = [
  { id: 1, username: 'user1', password: '$2a$10$...' } // hashed password
];

Hashing Passwords

Use bcryptjs to hash passwords before storing them.

const bcrypt = require('bcryptjs');

const hashedPassword = bcrypt.hashSync('password123', 10);
console.log(hashedPassword);

Step 4: Configure Passport Strategies

Set up the local strategy for username and password authentication:

const LocalStrategy = require('passport-local').Strategy;

passport.use(new LocalStrategy(
  function(username, password, done) {
    const user = users.find(u => u.username === username);
    if (!user) {
      return done(null, false, { message: 'Incorrect username.' });
    }
    if (!bcrypt.compareSync(password, user.password)) {
      return done(null, false, { message: 'Incorrect password.' });
    }
    return done(null, user);
  }
));

Step 5: Serialize and Deserialize Users

Manage user sessions with serializeUser and deserializeUser:

passport.serializeUser(function(user, done) {
  done(null, user.id);
});

passport.deserializeUser(function(id, done) {
  const user = users.find(u => u.id === id);
  done(null, user);
});

Step 6: Create Authentication Routes

Implement login and logout routes:

app.post('/login',
  passport.authenticate('local', {
    successRedirect: '/dashboard',
    failureRedirect: '/login'
  })
);

app.get('/logout', (req, res) => {
  req.logout();
  res.redirect('/');
});

Step 7: Protect Routes

Create middleware to check authentication:

function ensureAuthenticated(req, res, next) {
  if (req.isAuthenticated()) {
    return next();
  }
  res.redirect('/login');
}

Apply this middleware to protected routes:

app.get('/dashboard', ensureAuthenticated, (req, res) => {
  res.send('Welcome to your dashboard, ' + req.user.username);
});

Step 8: Run Your Application

Start your server:

app.listen(3000, () => {
  console.log('Server started on http://localhost:3000');
});

Navigate to http://localhost:3000/login to test authentication.

Conclusion

With these steps, you have integrated Passport.js into your Express application for secure user authentication. You can extend this setup by adding registration, password reset, and integrating with databases for persistent user management.