I want to implement the function that checks if there is a token, verifies the token and grants access to the protected route but I dont know how to send user data to the next function.
authController.js file –
exports.protect = async (req, res, next) => {
//1) Getting token and check if it's there
let token;
if (
req.headers.authorization &&
req.headers.authorization.startsWith("Bearer")
) {
token = req.headers.authorization.split(" ")[1];
} else if (req.cookies.jwt) {
token = req.cookies.jwt;
}
if (!token) {
res.status(401).json({
status: "fail",
message: "You are not logged in. Please login to get access",
});
next();
}
//2) Verificating the token
//const decoded = await promisify(jwt.verify)(token, process.env.JWT_SECRET);
const decoded = jwt.verify(token, process.env.JWT_SECRET);
let currentUser;
//3)Check if user still exists
db.getConnection(async (err, connection) => {
const sqlSearch = "SELECT * FROM users WHERE id = ?";
const sqlQuery = mysql.format(sqlSearch, [decoded.id]);
connection.query(sqlQuery, (err, result) => {
connection.release();
currentUser = result;
});
});
if (!currentUser) {
res.status(401).json({
status: "fail",
message: "The user belonging to this token does no longer exist",
});
next();
}
//GRANT ACCESS TO PROTECTED ROUTE
req.user = currentUser;
res.locals.user = currentUser;
next();
};
courseRouter.js file –
const express = require('express');
const coursesController = require('../controllers/coursesController');
const authController = require('../controllers/authController');
const router = express.Router();
router.get('/', coursesController.getAllCourses);
router.post('/:slug', authController.protect, coursesController.buyCourse);
module.exports = router;
After connecting to the database i don’t know how to return user data to the buyCourse() function. The way I did it the "currentUser" is undefined.
2
Answers
I would suggest using
AsyncLocalStorage
for storing the logged-in user on a context-based storage and granting access to any function down the chain. This would ensure that the logged-in user’s context is maintained across different function calls within the same execution context.You can refer to the Node.js documentation for usage: https://nodejs.org/api/async_context.html
AsyncLocalStorage
is a singleton instance, and you can use itsrun()
method on every incoming request to set up the context and store the logged-in user information.Your use of
response.locals.user
looks pretty standard. DeclarebuyCourse
to accept request and response objects like this:But you are not awaiting the database results, so
currentUser
is still null when you set it. Try writing it like this instead: