Technologies
1
npm install bcryptjs jsonwebtoken
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);
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;
1
2
const authRoutes = require('./routes/auth');
app.use('/api/auth', authRoutes);
1
2
3
4
{
"email": "test@example.com",
"password": "password123"
}
1
2
3
4
{
"email": "test@example.com",
"password": "password123"
}
After login, check browser or Postman cookies: you should see a token cookie.
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
2
3
4
{
"email": "test@example.com",
"password": "123456"
}