Enhancing JWT Authentication in Node.js
JSON Web Tokens (JWTs) are a popular way to authenticate and authorize users in web applications. They consist of three parts: a header, a payload, and a signature. The header contains information about the token, such as the algorithm used for signing. The payload contains the claims, which are statements about the user. The signature is a hash of the header, payload, and a secret key, which ensures the integrity of the token.
To get started, you’ll need to install the necessary dependencies. Open your terminal and navigate to your Node.js project directory. Then run the following command:
npm install express jsonwebtoken
Now, let’s create an Express application that handles user authentication using JWTs. Create a new file, for example, app.js, and add the following code:
const express = require('express');
const jwt = require('jsonwebtoken');
const app = express();
app.use(express.json());
const secretKey = 'your-secret-key';
// Endpoint for generating and returning a JWT token
app.post('/login', (req, res) => {
// In a real-world scenario, you would typically validate the user's credentials here
const { username, password } = req.body;
// Check if the username and password are correct
if (username === 'john' && password === 'password') {
// Generate a JWT token
const token = jwt.sign({ username }, secretKey, { expiresIn: '1h' });
// Return the token to the client
res.json({ token });
} else {
res.status(401).json({ message: 'Invalid username or password' });
}
});
// Protected endpoint that requires a valid JWT token
app.get('/protected', authenticateToken, (req, res) => {
res.json({ message: 'You are authorized to access this protected resource.' });
});
// Middleware for authenticating JWT token
function authenticateToken(req, res, next) {
// Extract the token from the Authorization header
const authHeader = req.headers['authorization'];
const token = authHeader && authHeader.split(' ')[1];
if (!token) {
return res.status(401).json({ message: 'No token provided' });
}
// Verify and decode the token
jwt.verify(token, secretKey, (err, decoded) => {
if (err) {
return res.status(403).json({ message: 'Invalid token' });
}
// Add the decoded user information to the request object
req.user = decoded;
next();
});
}
// Start the server
app.listen(3000, () => {
console.log('Server started on port 3000');
});
In this example, we have two endpoints: /login for generating a JWT token, and /protected as a protected resource that requires a valid token for access.
When a user makes a POST request to /login with a JSON payload containing their username and password, we check if the provided credentials are valid. If they are, we generate a JWT token using jwt.sign(), passing in the username as the payload. The secretKey is used to sign the token, and we also specify an expiration time of 1 hour.