Overview
A Node.js library for use as Express middleware to secure endpoints with JWTs. The implementation uses a JWT endpoint of an Authorization Server to get the keys required for verification of the token signature. There is also an example Express app that shows how to use the library.
Package: https://www.npmjs.com/package/jsonwebtoken
Using the JSON web token, we can simply authenticate each and every request on our server. As a standard / best practice, we can use JWT (JSON web token) middleware to validate all requests.
JWT Middleware
const jwt = require('jsonwebtoken')
module.exports = (expectedRole) => (req, res, next) => {
const authHeader = req.get('Authorization')
if (!authHeader) {
const error = new Error('Not authenticated.')
error.statusCode = 401
throw error
}
const token = authHeader.split(' ')[1]
if (!token) {
const error = new Error('Not authenticated.')
error.statusCode = 401
throw error
}
let decodedToken
try {
decodedToken = jwt.verify(token, process.env.SECRET_KEY)
} catch (error) {
error.statusCode = 401
throw error
}
if (!decodedToken) {
const error = new Error('Not authenticated.')
error.statusCode = 401
throw error
}
const role = decodedToken.role
const authorised = expectedRole.includes(role)
if (!authorised) {
const error = new Error('Not authorised.')
error.statusCode = 401
throw error
}
req.user = decodedToken
next()
}
This middleware has been prepared and exported. Therefore, we need to include it in our routes file and pass it to the expected role, so in our JWT middleware, we will validate the request with the JWT token, then verify that the user has access to an expected role (this role saved in the database) to this endpoint.
Routes File
const express = require('express')
const router = express.Router()
const auth = require('./auth/index')
const admin = require('./admin/index')
const common = require('./common/index')
const authorize = require('../middleware/jwtAuth')
router.use('/auth', auth)
router.use('/admin', authorize(['admin']), admin)
router.use('/common', authorize(['admin', 'user']), common)
module.exports = router
Now that we have set up our authentication and authorization middleware in our routes, we are passing the required role to access these routes. These roles will be checked against our user role.
Our middleware simply next() the request if the user has a valid JWT token and is authorized to access this route, otherwise, it will throw the global error that is caught by the express global error handler.