Skip to content

Instantly share code, notes, and snippets.

@yvki
Created January 4, 2024 09:34
Show Gist options
  • Save yvki/d4ebe1f0df59e7131cb0cadd763a2b5c to your computer and use it in GitHub Desktop.
Save yvki/d4ebe1f0df59e7131cb0cadd763a2b5c to your computer and use it in GitHub Desktop.
JavaScript implementation for verification of JSON Web Token (JWT) ✅
// 1. create a backend file with middleware function to check if user is logged in within 3 steps, note that the following snippet is a sample function asserting that a given token not only follows a proper JWT format, but also it's signature matches during the encoding and decoding process, so as to grant actions entitled to a privileged user
// 1.1 import modules
const jwt = require("jsonwebtoken");
const JWT_SECRET = process.env.JWT_SECRET;
// 1.2 declare token verification function
function verifyToken(req, res, next) {
const authHeader = req.headers.authorization;
// 1.2.1 check if the header contains the authorization information
if (authHeader === null || authHeader === undefined || !authHeader.startsWith("Bearer ")) {
res.status(401).send("Unauthorized. [1]"); // username does not exist or password provided is incorrect
return;
}
// 1.2.2 extract the token
const token = authHeader.replace("Bearer ", "");
var options = {
algorithms: ["HS256"]
}
// 1.2.3 verify the token
jwt.verify(token, JWT_SECRET, options, function (error, decodedToken) {
if (error) {
res.status(401).send("Unauthorized. [2]"); // token doesn't match
return;
}
// 1.2.3.1 take the decoded token and save it in the request object so that other middleware functions below have access to it
req.decodedToken = decodedToken;
// 1.2.3.2 call the next middleware function
next();
});
};
// 1.3 export token verification function
module.exports = verifyToken;
// 2. create another backend file with functions for special service requests from priviledged users (ie. admins), note that the following snippet is a sample function detailing 2 use cases where a) only admin can see list of registered member(s) and b) only admin can update registered member(s) detail(s), which can modified to your own requirements
// 2.1 import previously created token verification function
const isLoggedInMiddleware = require("../isLoggedInMiddleware");
// 2.2 create GET function to retrieve list of user(s) detail(s) by their id
app.get("/users/:id/", isLoggedInMiddleware, (req, res, next) => {
console.log("Last MF for servicing GET/users/:id/...");
//2.1.1 request for user id through parameters
const id = parseInt(req.params.id);
if (isNaN(id)) { //case if user id entered is not a number
res.status(400).send(); //case if user id not found or/ is invalid
return;
}
//2.1.2 contact the model layer
User.findByID(id, (error, user) => {
if (error) {
res.status(500).send(); //case if internal server error
return;
};
if (user === null) {
res.status(404).send(); //case if user id not found/ is empty
return;
};
res.status(200).send(user); //case if OK
});
});
// 2.3 create PUT function to update list of user(s) detail(s) by their id
app.put("/users/:userID/", isLoggedInMiddleware, (req, res, next) => {
console.log("Last MF for servicing PUT/users/:userID/...");
//assuming we want to update user details
console.log(req.body);
//request for user id through parameters
const userID = parseInt(req.params.userID);
if (isNaN(userID)) { // case if user id entered is not a number
res.status(400).send(); // case if user id cannot be requested
return;
};
//contact the model layer
User.edit(userID, req.body, (error, results) => {
if (error) {
if (error.errno === 1062) {
// cannot use back the same username for a different user id
res.status(442).send("The new username provided already exists.");
return;
};
if (error) {
console.log(error);
res.status(500).send("'Result':'Internal Server Error'");
return;
};
} else {
if (results.changedRows === 0) {
// case if username for user id is same as that of another user id
res.status(422).send("The new username provided already exists.");
return;
} else {
//package output
res.status(200).send({
success: true,
status: "Record updated successfully!"
});
}
};
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment