Task 10: Authentication and Authorization using Node.js, Express, MongoDB, and JWT.
✅ Step-by-Step Guide:
1. Setup Project
mkdir jwt-auth-app
cd jwt-auth-app
npm init -y
npm install express mongoose jsonwebtoken bcryptjs dotenv
2. File Structure
jwt-auth-app/
├── .env
├── server.js
├── models/
│ └── User.js
├── middleware/
│ └── auth.js
└── routes/
└── auth.js
3. .env File
PORT=5000
MONGO_URI=mongodb://localhost:27017/jwt-auth-db
JWT_SECRET=your_jwt_secret_key
4. MongoDB User Model (models/User.js)
const mongoose = require('mongoose');
const bcrypt = require('bcryptjs');
const UserSchema = new mongoose.Schema({
username: { type: String, required: true, unique: true },
password: { type: String, required: true },
});
UserSchema.pre('save', async function (next) {
if (!this.isModified('password')) return next();
this.password = await bcrypt.hash(this.password, 10);
next();
});
UserSchema.methods.comparePassword = function (password) {
return bcrypt.compare(password, this.password);
};
module.exports = mongoose.model('User', UserSchema);
5. Auth Middleware (middleware/auth.js)
const jwt = require('jsonwebtoken');
const dotenv = require('dotenv');
dotenv.config();
module.exports = function (req, res, next) {
const token = req.header('Authorization')?.split(' ')[1];
if (!token) return res.status(401).json({ message: 'Access Denied: No Token Provided' });
try {
const decoded = jwt.verify(token, process.env.JWT_SECRET);
req.user = decoded;
next();
} catch (err) {
res.status(400).json({ message: 'Invalid Token' });
}
};
6. Auth Routes (routes/auth.js)
const express = require('express');
const jwt = require('jsonwebtoken');
const User = require('../models/User');
const auth = require('../middleware/auth');
const dotenv = require('dotenv');
dotenv.config();
const router = express.Router();
// Register
router.post('/register', async (req, res) => {
const { username, password } = req.body;
try {
const user = new User({ username, password });
await user.save();
res.status(201).json({ message: 'User registered' });
} catch (err) {
res.status(400).json({ message: 'User already exists' });
}
});
// Login
router.post('/login', async (req, res) => {
const { username, password } = req.body;
const user = await User.findOne({ username });
if (!user || !(await user.comparePassword(password)))
return res.status(401).json({ message: 'Invalid credentials' });
const token = jwt.sign({ id: user._id, username: user.username }, process.env.JWT_SECRET, {
expiresIn: '1h',
});
res.json({ token });
});
// Protected route
router.get('/protected', auth, (req, res) => {
res.json({ message: `Hello ${req.user.username}, you accessed a protected route!` });
});
module.exports = router;
7. Server Setup (server.js)
const express = require('express');
const mongoose = require('mongoose');
const dotenv = require('dotenv');
const authRoutes = require('./routes/auth');
dotenv.config();
const app = express();
app.use(express.json());
// Connect to MongoDB
mongoose.connect(process.env.MONGO_URI, {
useNewUrlParser: true,
useUnifiedTopology: true,
}).then(() => console.log('MongoDB Connected'))
.catch(err => console.error('MongoDB Connection Error:', err));
// Routes
app.use('/api', authRoutes);
// Start server
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
🧪 Test Your Server
1. Register: POST /api/register
{
"username": "testuser",
"password": "password123"
}
2. Login: POST /api/login
Response will include a token.
3. Protected Route: GET /api/protected
Add Authorization: Bearer <token> in headers.