Express JS JWT
Job-ready Online Courses: Dive into Knowledge. Learn More!
JSON Web Tokens (JWT) in Express JS is used for transmitting information between parties as a JSON object. It is used for authentication and authorization purposes in web apps. In this article, we will explore how to use JWT for authentication in an Express.js application.
Prerequisites to use Express JWT
Before diving into JWT authentication, you should have a basic understanding of Node.js, Express.js, and MongoDB. You should also have the following packages installed in your project:
- express
- mongoose
- bcrypt
- Jsonwebtoken
JSON Web Token JWT structure
A JWT consists of three parts: a header, a payload, and a signature.
1. Header:
The header of a JWT is a JSON object that describes the cryptographic operations used to generate the signature. It typically contains two fields:
- “alg” (algorithm): The algorithm used to sign the token. Common values include HMAC SHA256 and RSA.
- “typ” (type): The type of token, which is always “JWT”.
The header is Base64Url-encoded to create the first part of the JWT.
2. Payload:
The payload of a JWT contains the claims, or statements, about an entity (typically, the user) and additional data. Claims can be of three types:
a. Registered claims: These are predefined claims that are recommended but not required to be used in a JWT. Examples include “iss” (issuer), “exp” (expiration time), and “sub” (subject).
b. Public claims: These are custom claims that are defined by the parties that use them. They should be defined in a namespace that avoids collisions with other names.
c. Private claims: These are custom claims that are defined by the parties that use them. They are not meant to be shared with other parties.
The payload is also a JSON object, which is Base64Url-encoded to create the second part of the JWT.
3. Signature:
The signature of a JWT is used to verify that the sender of the JWT is who it says it is and to ensure that the message was not changed along the way. This is created by taking the encoded header, the encoded payload, a secret key, and the algorithm specified in the header and signing them. It is then added to the JWT as the third part.
Creating the Express Application
First, let’s create a new Express application using the following commands:
mkdir express-jwt-auth cd express-jwt-auth npm init -y npm install express mongoose bcrypt jsonwebtoken
The above commands create a new directory called express-jwt-auth, initializes a new Node.js project with default values, and installs the required dependencies.
Next, create a new file called app.js in the project root directory and add the following code:
const express = require('express');
const mongoose = require('mongoose');
const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken');
const app = express();
const port = 3000;
app.use(express.json());
mongoose.connect('mongodb://localhost/jwt-auth', {
useNewUrlParser: true,
useUnifiedTopology: true
})
.then(() => console.log('Connected to MongoDB'))
.catch(err => console.log(err));
app.listen(port, () => console.log(`Server running on port ${port}`));
In the above code, we require the required packages, initialize a new Express application, set the listening port to 3000, and connect to a MongoDB database named jwt-auth.
Creating a User Model
Next, let’s create a new user model that will be used for authentication. Create a new file called models/User.js and add the following code:
const mongoose = require('mongoose');
const bcrypt = require('bcrypt');
const userSchema = new mongoose.Schema({
username: {
type: String,
required: true,
unique: true
},
password: {
type: String,
required: true
}
});
userSchema.pre('save', async function (next) {
const user = this;
if (user.isModified('password')) {
const salt = await bcrypt.genSalt();
user.password = await bcrypt.hash(user.password, salt);
}
next();
});
userSchema.statics.authenticate = async function (username, password) {
const user = await this.findOne({ username });
if (!user) {
throw new Error('Invalid username');
}
const isMatch = await bcrypt.compare(password, user.password);
if (!isMatch) {
throw new Error('Invalid password');
}
return user;
};
const User = mongoose.model('User', userSchema);
module.exports = User;
In the above code, we define a new user schema with two fields – username and password. We also define a pre-save hook that hashes the password before saving it to the database. We also define a static method called authenticate that takes a username and password and returns the user if the credentials are valid, or throws an error otherwise.
Creating Authentication Routes
Next, let’s create the authentication routes that will handle user registration and login. In the app.js file, add the following code:
const User = require('./models/User');
app.post('/register', async (req, res) => {
const { username, password } = req.body;
try {
const user = new User({ username, password });
await user.save();
res.status(201).
res.json({ message: 'User created successfully' });
} catch (err) {
res.status(400).json({ error: err.message });
}
});
app.post('/login', async (req, res) => {
const { username, password } = req.body;
try {
const user = await User.authenticate(username, password);
const token = jwt.sign({ userId: user._id }, 'secret');
res.json({ token });
} catch (err) {
res.status(400).json({ error: err.message });
}
});
In the above code, we define two routes – `/register` and `/login`. The `register` route creates a new user and saves it to the database. The `login` route authenticates the user using the `authenticate` method of the user model and returns a JWT token if the authentication is successful.
Using the JWT Token for Authentication
Now that we have the JWT token, let’s use it to authenticate users. In the `app.js` file, add the following middleware:
const requireAuth = (req, res, next) => {
const token = req.headers.authorization?.split(' ')[1];
if (token) {
jwt.verify(token, 'secret', (err, decodedToken) => {
if (err) {
res.status(401).json({ error: 'Unauthorized' });
} else {
req.userId = decodedToken.userId;
next();
}
});
} else {
res.status(401).json({ error: 'Unauthorized' });
}
};
app.get('/profile', requireAuth, (req, res) => {
res.json({ userId: req.userId });
});
In the above code, we define a middleware called requireAuth that checks for a JWT token in the Authorization header of the request. If the token is present, it verifies the token and sets the userId property of the request object. If the token is not present or invalid, it returns an error response. We also define a new route called /profile that requires authentication and returns the userId of the authenticated user.
Conclusion
In this article, we have explored how to use JWT for authentication in an Express.js application. We have created a new user model, defined authentication routes, and used JWT tokens for authentication. We have also defined a middleware that checks for a JWT token and authenticates users.
Did you like this article? If Yes, please give DataFlair 5 Stars on Google



This is hands down the best explanation on jwt, as I had my interviews and couldn’t understand the official docs.
Kudos to your team of writers.