Implementing user authentication in Express.js

Implementing User Authentication in Express.js

User authentication is a crucial aspect of web application development. It ensures that users can securely access their accounts while protecting sensitive data. In this article, we’ll explore how to implement user authentication in Express.js, a popular web framework for Node.js. We'll cover definitions, use cases, and actionable insights, complete with code examples and step-by-step instructions.

What is User Authentication?

User authentication is the process of verifying a user's identity before granting access to specific resources or actions. It typically involves the user providing credentials, such as a username and password, which the system checks against its records.

Why Use User Authentication?

  • Security: Protects sensitive data from unauthorized access.
  • Personalization: Allows for user-specific data and experiences.
  • Accountability: Keeps track of user actions and history.

Use Cases for User Authentication

  • Social Media Platforms: Allow users to create profiles, interact, and share content.
  • E-commerce Websites: Enable users to manage orders, save payment information, and track shipping.
  • Enterprise Applications: Secure access to company resources and sensitive information.

Setting Up Express.js for User Authentication

Prerequisites

Before diving into the code, ensure you have the following installed:

  • Node.js
  • npm (Node Package Manager)

Step 1: Initialize Your Project

Create a new directory for your project and initialize it:

mkdir express-auth
cd express-auth
npm init -y

Step 2: Install Required Packages

You’ll need the following packages for user authentication:

  • express: The web framework.
  • mongoose: For MongoDB object modeling.
  • bcrypt: To hash passwords.
  • jsonwebtoken: To create tokens for user sessions.
  • express-session: To manage user sessions.

Install these packages using npm:

npm install express mongoose bcrypt jsonwebtoken express-session

Step 3: Set Up the Express Server

Create an index.js file and set up a basic Express server:

const express = require('express');
const mongoose = require('mongoose');
const session = require('express-session');

const app = express();
app.use(express.json());
app.use(session({
  secret: 'your_secret_key',
  resave: false,
  saveUninitialized: true,
}));

mongoose.connect('mongodb://localhost:27017/authDemo', { useNewUrlParser: true, useUnifiedTopology: true })
  .then(() => console.log('MongoDB connected'))
  .catch(err => console.log(err));

const PORT = process.env.PORT || 3000;

app.listen(PORT, () => {
  console.log(`Server is running on port ${PORT}`);
});

Step 4: Create a User Model

Next, create a user model to define how user data will be stored in MongoDB. Create a new file called User.js:

const mongoose = require('mongoose');

const UserSchema = new mongoose.Schema({
  username: { type: String, required: true, unique: true },
  password: { type: String, required: true },
});

module.exports = mongoose.model('User', UserSchema);

Step 5: Implement Registration

Now, let’s implement user registration. Add the following route in your index.js:

const User = require('./User');

app.post('/register', async (req, res) => {
  const { username, password } = req.body;

  // Hash the password
  const hashedPassword = await bcrypt.hash(password, 10);

  const newUser = new User({ username, password: hashedPassword });

  try {
    await newUser.save();
    res.status(201).send('User registered successfully!');
  } catch (error) {
    res.status(400).send('Error registering user: ' + error.message);
  }
});

Step 6: Implement Login

Next, implement the login functionality. Add the following route:

app.post('/login', async (req, res) => {
  const { username, password } = req.body;

  const user = await User.findOne({ username });
  if (!user) return res.status(400).send('User not found');

  const isMatch = await bcrypt.compare(password, user.password);
  if (!isMatch) return res.status(400).send('Invalid credentials');

  // Create a token
  const token = jwt.sign({ id: user._id }, 'your_jwt_secret', { expiresIn: '1h' });
  req.session.token = token; // Save token in session
  res.send('Login successful!');
});

Step 7: Protect Routes

To protect certain routes, you can create middleware to check for the JWT token. Here’s how you can do it:

const authenticate = (req, res, next) => {
  const token = req.session.token;
  if (!token) return res.status(403).send('Access denied');

  jwt.verify(token, 'your_jwt_secret', (err) => {
    if (err) return res.status(403).send('Invalid token');
    next();
  });
};

// Example of a protected route
app.get('/protected', authenticate, (req, res) => {
  res.send('This is a protected route');
});

Step 8: Testing Your Authentication System

Use tools like Postman or Insomnia to test your registration and login routes. Check whether you can access the protected route after logging in.

Troubleshooting Common Issues

  • Database Connection Errors: Ensure your MongoDB service is running and your connection string is correct.
  • JWT Issues: If you encounter token-related errors, verify that the JWT secret matches in both the login and authentication middleware.
  • Password Hashing Errors: Ensure that bcrypt is properly installed and imported.

Conclusion

Implementing user authentication in Express.js is a fundamental skill for any web developer. With the steps outlined in this guide, you can create a secure authentication system that protects user data and enhances your application's functionality. By using tools like MongoDB, bcrypt, and JWT, you can build a robust authentication mechanism with ease.

Now, get started on your Express.js project and enhance your web applications with secure user authentication!

SR
Syed
Rizwan

About the Author

Syed Rizwan is a Machine Learning Engineer with 5 years of experience in AI, IoT, and Industrial Automation.