Here's a simple example of how to implement authentication with Node.js using JWTs (JSON Web Tokens). This example will cover:
- Registering a user.
- Logging in a user to get a JWT token.
- Protecting routes with the JWT token.
Step 1: Setup and Install Required Packages
Create a new Node.js project and install the following dependencies:
npm init -y
npm install express bcryptjs jsonwebtoken mongoose
- express: To set up the server and routes.
- bcryptjs: To hash passwords.
- jsonwebtoken: To sign and verify JWT tokens.
- mongoose: To connect to MongoDB for storing user data.
Step 2: Create a Simple User Model with Mongoose
We'll use MongoDB to store user details. Set up the MongoDB connection and create a user model.
// models/User.js
const mongoose = require('mongoose');
const bcrypt = require('bcryptjs');
const UserSchema = new mongoose.Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true,
unique: true
},
password: {
type: String,
required: true
}
});
// Hash the password before saving
UserSchema.pre('save', async function (next) {
if (!this.isModified('password')) return next();
const salt = await bcrypt.genSalt(10);
this.password = await bcrypt.hash(this.password, salt);
next();
});
const User = mongoose.model('User', UserSchema);
module.exports = User;
Step 3: Set Up the Server and Authentication Routes
Now, set up the Express server and create routes for registration, login, and a protected route.
// server.js
const express = require('express');
const mongoose = require('mongoose');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const User = require('./models/User');
const app = express();
app.use(express.json());
// Connect to MongoDB
mongoose.connect('mongodb://localhost:27017/jwt-auth', {
useNewUrlParser: true,
useUnifiedTopology: true,
useCreateIndex: true
}).then(() => console.log('MongoDB connected'));
// Secret for JWT signing
const JWT_SECRET = 'supersecretjwtkey';
// Register User
app.post('/register', async (req, res) => {
const { name, email, password } = req.body;
try {
const user = new User({ name, email, password });
await user.save();
res.status(201).json({ message: 'User registered successfully!' });
} catch (error) {
res.status(400).json({ message: 'Error registering user' });
}
});
// Login User and generate JWT
app.post('/login', async (req, res) => {
const { email, password } = req.body;
try {
const user = await User.findOne({ email });
if (!user) return res.status(400).json({ message: 'User not found' });
const isMatch = await bcrypt.compare(password, user.password);
if (!isMatch) return res.status(400).json({ message: 'Invalid credentials' });
// Create and sign the JWT token
const token = jwt.sign({ userId: user._id }, JWT_SECRET, { expiresIn: '1h' });
res.json({ token });
} catch (error) {
res.status(500).json({ message: 'Server error' });
}
});
// Middleware to protect routes
const authenticateJWT = (req, res, next) => {
const token = req.header('Authorization')?.split(' ')[1];
if (!token) return res.status(401).json({ message: 'No token, authorization denied' });
try {
const decoded = jwt.verify(token, JWT_SECRET);
req.user = decoded.userId;
next();
} catch (err) {
res.status(403).json({ message: 'Invalid token' });
}
};
// Protected route
app.get('/protected', authenticateJWT, (req, res) => {
res.json({ message: 'You have access to the protected route!', userId: req.user });
});
// Start the server
app.listen(5000, () => console.log('Server running on port 5000'));
Step 4: Test the Application
You can now test the JWT authentication workflow using tools like Postman.
1. Register a User
- URL:
POST http://localhost:5000/register
- Body (JSON):
{
"name": "John Doe",
"email": "john@example.com",
"password": "password123"
}
This will register the user in MongoDB with the hashed password.
2. Login to Get the JWT Token
- URL:
POST http://localhost:5000/login
- Body (JSON):
{
"email": "john@example.com",
"password": "password123"
}
The server will return a JWT token:
{
"token": "your.jwt.token"
}
3. Access the Protected Route
- URL:
GET http://localhost:5000/protected
- Headers:
Authorization: Bearer your.jwt.token
If the token is valid, you will receive:
{
"message": "You have access to the protected route!",
"userId": "some-user-id"
}
If the token is missing or invalid, you will get an error message.
Summary
- User Registration: Users register with their name, email, and password, which is hashed and stored in the database.
- User Login: The user logs in by sending their email and password. If valid, the server returns a JWT.
- JWT Token: The JWT is stored on the client-side (usually in localStorage or cookies) and is sent with each request to protected routes.
- Protected Routes: The server verifies the JWT token on each request to ensure the user is authenticated.
Let me know if you'd like help with any specific part of the JWT authentication process!