i was told that using res.locals will decrease the performance of my application , and it's better to attach variables on the request. in my case i want to attach variables that are accessible only on the server side , and i don't want it to be sent back to the user , and i also came across sending the variable using next(value) , what is the best approach for my case??
i have this middleware that gets the id of the user from jwt
jwt.verify(
accessToken,
process.env.ACCESS_TOKEN_KEY,
function (err, payload) {
if (err)
return res.status(401).send({
status: "failure",
response: "access token is not valid",
});
id = payload.id;
}
);
res.locals.userId = id;
next();
then this middleware that gets the role of the user based on the id
const RoleId = await sequelize.models.User.findByPk(res.locals.userId);
if (RoleId === 1) {
res.locals.title = "Admin";
next();
} else {
res.locals.title = "Customer";
next();
}
CodePudding user response:
res.locals.xxx
will have no different performance from setting res.xxx
or req.xxx
. No difference at all. So, without a specific reference to whomever said one would be slower than the other that somehow has more context, that's not correct.
And, res.locals
are not sent to the client. Template engines doing server-side rendering by convention will look in res.locals
to find variables that the template may reference that were not explicitly passed to res.render()
. This is very useful for having common data (like a user's name) that you want the template to use, but don't want to have to manually pass to every single res.render()
call.
This is entirely under your control since you, on the server, control both the template and the server-side rendering. This allows you to insert things into the page which is then sent to the user, but nothing goes in the template that you don't put there. So, res.locals
is not a security risk unless you somehow give an outside agent control over your template (which would be subject to all sorts of security issues beyond just res.locals
.
Another advantage of res.locals
is that its an independent namespace that is entirely reserved for your use. No variable you use there will conflict with any existing functionality of the http
class or Express or whatever web server engine you're using. The res
object, on the other hand, has all sorts of existing methods and properties that you have to make sure you don't overwrite. So, res.locals
is safer in that regard as it is specifically reserved for your own use. You can put any named property in there without any risk of conflict.
Passing a value to next(value)
is how you abort further routing and immediately invoke your error handler, passing value
to the error handler. This is not how middleware communicates data to downstream routing or rendering.
Both your code examples look like proper use of res.locals
to me. That is exactly what it's for.
On a completely separate topic, your first code example has a coding error in it. You need to put these:
res.locals.userId = id;
next();
Inside the jwt.verify()
callback. jwt.verify()
is asynchronous. You won't have the id
value until that callback is called. It should be like this:
jwt.verify(accessToken, process.env.ACCESS_TOKEN_KEY, function(err, payload) {
if (err) {
return res.status(401).send({
status: "failure",
response: "access token is not valid",
});
}
res.locals.userId = payload.id;
next();
});