Loading...
Loading...
1This guide demonstrates how to implement JWT (JSON Web Token) authentication in a Node.js application using Express.js, Mongoose (MongoDB), bcryptjs, and the jsonwebtoken library.
2
3### 1. Setup and Dependencies
4
5bash
6mkdir jwt-auth-app && cd jwt-auth-app
7npm init -y
8npm install express jsonwebtoken bcryptjs dotenv mongoose
9
10
11### 2. Environment Variables (.env)
12
13env
14MONGO_URI=mongodb://127.0.0.1:27017/jwt_auth_db
15JWT_SECRET=your_strong_secret_key
16JWT_EXPIRES_IN=30d
17PORT=5000
18
19
20### 3. User Model (models/User.js)
21
22javascript
23const mongoose = require('mongoose');
24const bcrypt = require('bcryptjs');
25
26const userSchema = new mongoose.Schema({
27 name: { type: String, required: true },
28 email: { type: String, required: true, unique: true },
29 password: { type: String, required: true },
30}, { timestamps: true });
31
32userSchema.pre('save', async function (next) {
33 if (!this.isModified('password')) return next();
34 const salt = await bcrypt.genSalt(10);
35 this.password = await bcrypt.hash(this.password, salt);
36 next();
37});
38
39userSchema.methods.comparePassword = async function (password) {
40 return await bcrypt.compare(password, this.password);
41};
42
43module.exports = mongoose.model('User', userSchema);
44
45
46### 4. Auth Middleware (middleware/auth.js)
47
48javascript
49const jwt = require('jsonwebtoken');
50const User = require('../models/User');
51
52const generateToken = (id) => {
53 return jwt.sign({ id }, process.env.JWT_SECRET, {
54 expiresIn: process.env.JWT_EXPIRES_IN || '30d',
55 });
56};
57
58const protect = async (req, res, next) => {
59 let token;
60
61 if (req.headers.authorization && req.headers.authorization.startsWith('Bearer')) {
62 try {
63 token = req.headers.authorization.split(' ')[1];
64 const decoded = jwt.verify(token, process.env.JWT_SECRET);
65 req.user = await User.findById(decoded.id).select('-password');
66 next();
67 } catch (error) {
68 res.status(401).json({ message: 'Not authorized, token failed' });
69 }
70 }
71
72 if (!token) {
73 res.status(401).json({ message: 'Not authorized, no token' });
74 }
75};
76
77module.exports = { generateToken, protect };
78
79
80### 5. Auth Routes (routes/auth.js)
81
82javascript
83const express = require('express');
84const User = require('../models/User');
85const { generateToken, protect } = require('../middleware/auth');
86const router = express.Router();
87
88router.post('/register', async (req, res) => {
89 const { name, email, password } = req.body;
90 const userExists = await User.findOne({ email });
91 if (userExists) return res.status(400).json({ message: 'User already exists' });
92
93 const user = await User.create({ name, email, password });
94 res.status(201).json({
95 _id: user._id, name: user.name, email: user.email,
96 token: generateToken(user._id),
97 });
98});
99
100router.post('/login', async (req, res) => {
101 const { email, password } = req.body;
102 const user = await User.findOne({ email });
103 if (user && (await user.comparePassword(password))) {
104 res.json({
105 _id: user._id, name: user.name, email: user.email,
106 token: generateToken(user._id),
107 });
108 } else {
109 res.status(401).json({ message: 'Invalid email or password' });
110 }
111});
112
113router.get('/profile', protect, (req, res) => {
114 res.json(req.user);
115});
116
117module.exports = router;
118
119
120### 6. Server (server.js)
121
122javascript
123require('dotenv').config();
124const express = require('express');
125const mongoose = require('mongoose');
126const authRoutes = require('./routes/auth');
127
128const app = express();
129app.use(express.json());
130app.use('/api/auth', authRoutes);
131
132mongoose.connect(process.env.MONGO_URI)
133 .then(() => {
134 console.log('MongoDB connected');
135 app.listen(process.env.PORT || 5000, () => {
136 console.log(`Server running on port ${process.env.PORT || 5000}`);
137 });
138 })
139 .catch(err => console.log(err));
140
141
142### 7. Testing & Security
143
144**Register:** `POST /api/auth/register` with body `{ "name": "John", "email": "john@test.com", "password": "123456" }`
145
146**Login:** `POST /api/auth/login` with body `{ "email": "john@test.com", "password": "123456" }`
147
148**Protected Profile:** `GET /api/auth/profile` with Header `Authorization: Bearer <TOKEN>`
149
150Store your `JWT_SECRET` safely, use HTTPS in production, and consider implementing refresh tokens for long-lived sessions. Validate user inputs with libraries like `express-validator`.
151