JWT is a standard for securely transmitting information between parties as a JSON object. It consists of three parts: header, payload, and signature. The header specifies the algorithm used to sign the token, the payload contains the data being transmitted, and the signature is used to verify the integrity of the data.
Passport.js, on the other hand, is a middleware for Node.js that provides authentication strategies for various authentication providers, such as username/password, social media, and JWT. It simplifies the process of implementing authentication in a web application.
When using JWT with Passport.js, the JWT strategy can be used to authenticate users based on the JWT sent with the request. Passport.js verifies the signature of the token and extracts the payload to obtain the user’s information. If the user is authenticated, Passport.js can then proceed with the appropriate action, such as allowing the user to access a protected resource.
How to use JSON Web Token (JWT) and Passport.js together for authentication in a Node.js application
First, let’s install the necessary packages:
npm install jsonwebtoken passport passport-jwt
Then, let’s create a simple Express server:
const express = require('express');
const bodyParser = require('body-parser');
const passport = require('passport');
const JwtStrategy = require('passport-jwt').Strategy;
const ExtractJwt = require('passport-jwt').ExtractJwt;
const jwt = require('jsonwebtoken');
const app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(passport.initialize());
const jwtOptions = {
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKey: 'secret'
};
passport.use(new JwtStrategy(jwtOptions, (jwtPayload, done) => {
if (jwtPayload.sub === 'user123') {
done(null, { id: 'user123' });
} else {
done(null, false);
}
}));
app.post('/login', (req, res) => {
const { username, password } = req.body;
if (username === 'user123' && password === 'password123') {
const token = jwt.sign({ sub: 'user123' }, 'secret');
res.json({ token });
} else {
res.status(401).send('Invalid credentials');
}
});
app.get('/protected', passport.authenticate('jwt', { session: false }), (req, res) => {
res.json({ message: 'You are authorized to access this resource' });
});
app.listen(3000, () => {
console.log('Server started on port 3000');
});
In this example, we’ve defined a JWT strategy using Passport.js that extracts the JWT from the Authorization header and verifies its signature using a secret key. The strategy then checks if the JWT payload has a sub
property with the value ‘user123’. If it does, the strategy returns a user object with an id property set to ‘user123’. Otherwise, the strategy returns false.
We’ve also defined a /login the route that takes a username and password from the request body and returns a JWT if the credentials are valid. The JWT is signed with the same secret key used by the JWT strategy.
Finally, we’ve defined a /protected the route that requires authentication using the JWT strategy. If the user is authenticated, the route returns a JSON object with a message indicating that the user is authorized to access the resource.
To test this example, you can send a POST request /login with the credentials { “username”: “user123”, “password”: “password123” }. This should return a JSON object with a token property containing the JWT.
You can then send a GET request to /protected with an Authorization header containing the JWT as a bearer token. This should return a JSON object with a message indicating that you are authorized to access the resource.
If you try to access /protected without a valid JWT, you should receive a 401 Unauthorized response.
Overall, JWT and Passport.js are powerful tools for web development, providing secure and flexible authentication and authorization solutions.