Technologies

1. Install Required Packages

1
npm install bcryptjs jsonwebtoken

2. Create the User Schema

In models/User.js:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
const mongoose = require('mongoose');

const UserSchema = new mongoose.Schema({
  email: {
    type: String,
    required: true,
    unique: true,
    lowercase: true
  },
  password: {
    type: String,
    required: true
  },
  role: {
    type: String,
    default: 'customer',
    enum: ['customer', 'admin']
  }
}, { timestamps: true });

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

3. Create Authentication Routes

Create routes/auth.js:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
const express = require('express');
const router = express.Router();
const User = require('../models/User');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');

// Register
router.post('/register', async (req, res) => {
  const { email, password } = req.body;

  try {
    const exists = await User.findOne({ email });
    if (exists) return res.status(400).json({ msg: 'User already exists' });

    const hashedPassword = await bcrypt.hash(password, 10);
    const user = new User({ email, password: hashedPassword });
    await user.save();

    res.status(201).json({ msg: 'User registered successfully' });
  } catch (err) {
    res.status(500).json({ msg: 'Server error' });
  }
});

// Login
router.post('/login', async (req, res) => {
  const { email, password } = req.body;

  try {
    const user = await User.findOne({ email });
    if (!user) return res.status(400).json({ msg: 'Invalid credentials' });

    const isMatch = await bcrypt.compare(password, user.password);
    if (!isMatch) return res.status(400).json({ msg: 'Invalid credentials' });

    const token = jwt.sign(
      { id: user._id, role: user.role },
      process.env.JWT_SECRET,
      { expiresIn: '2h' }
    );

    res.cookie('token', token, {
      httpOnly: true,
      secure: false, // set to true in production with HTTPS
      maxAge: 2 * 60 * 60 * 1000
    });

    res.json({ msg: 'Login successful' });
  } catch (err) {
    res.status(500).json({ msg: 'Server error' });
  }
});

module.exports = router;

4. Register the Route in app.js

1
2
const authRoutes = require('./routes/auth');
app.use('/api/auth', authRoutes);

5. Test with Postman

1
2
3
4
{
  "email": "test@example.com",
  "password": "password123"
}

After login, check browser or Postman cookies: you should see a token cookie.

6. Create Auth Middleware

Create middleware/auth.js:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const jwt = require('jsonwebtoken');

const verifyToken = (req, res, next) => {
  const token = req.cookies.token;
  if (!token) return res.status(401).json({ msg: 'Unauthorized' });

  try {
    const decoded = jwt.verify(token, process.env.JWT_SECRET);
    req.user = decoded; // Contains { id, role }
    next();
  } catch (err) {
    res.status(403).json({ msg: 'Token is not valid' });
  }
};

module.exports = verifyToken;

Use it in protected routes like this:

1
2
3
4
const auth = require('../middleware/auth');
router.get('/protected', auth, (req, res) => {
  res.json({ msg: `Hello ${req.user.id}, you are authorized.` });
});
  1. Test with Postman

    Register:

Login: