Always pass variable to Express res.render - node.js

Is it possible to always pass certain variables to res.render by default?
More specifically, I'm using the passport middleware that populates req.user with the current user. I need to access this on every page in my site.
It's tedious to supply it each time -- and if I forget, it appears as if the user is not logged in.

A simple solution would be to create your own middleware :
function userView(req, res, next) {
res.locals.user = req.user;
next();
}
//...
app.use(passport.initialize());
app.use(passport.session());
//...
app.use(userView);
For each request, This populates a local variable user which is then accessible to the view(s) rendered later in the chain. Activate this middleware after the passport one or req.user will be undefined.

Related

router.param not triggering passport.js initialize in app.use

I've got a fairly straight forward Node Express routing app set up, to which I've just added passport.js authentication. I'm now trying to integrate this with the existing routes.
I run the basic middleware of:
app.use(passport.initialize());
app.use(passport.session());
and then if I run a simple
app.get('/route', (req, res)=>{
console.log(req.user)
});
I get the expected result of it printing the logged in user. So far so good...
However, I'm now trying to access this req.user within some of the child routes that I have set up. In the first route I'm trying the first step is to bring in a parameter and compare it against the req.user:
app.use('/route/:userId', idRouter);
And then:
idRouter.param("userId", async (req, res, next, userId) => {
console.log(userId)
console.log(req.user.id)
})
This route fires and prints out the parameter, but req.user is undefined. I can't see a reason why this is the case.
To help debug this I've put some logging in the deserialize function and I can see that it's not being called when I hit the idRouter. I can't see why this would be the case given it's inside an app.use function which should be called every time.
Help please!
I solved this in the end, it was an issue with CORS. Just needed to include credentials in API calls.

Does user/website has access to express res.locals variables?

I'm currently creating a Node app with Express and Passport and using this middleware in my main server.js file:
// Function to protect urls
function isProtected(req, res, next) {
if (req.isAuthenticated()) {
// User is logged in
res.locals.user = req.user;
return next();
}
// User is not logged in. Redirect to login.
res.redirect('login');
}
app.use('/protected_path', isProtected, protectedRouter);
My questions targets this line:
res.locals.user = req.user;
The user object is passed to res.locals so it can be used to populate fields like name, user role, date of registration, ...
Is there a way a user/website/api program (like Postman) can access the "res.locals" variables? There may be some sensitive data inside the req.user object and I just want to use the "res.locals" to get data which will be rendered in views like the profile page.
I could just pass the necessary variables into res.locals but this can get quite messy.
My last approach was to 'blacklist' the unnecessary variables described here: SO: How to omit specific properties from an object in JavaScript
Can the user access res.locals variables and therefore would it be security relevant? I would prefer my current solution if not.
No, they cannot access res.locals unless you give them to them yourself in a view or in some other way. Some details can be found in the documentation.

How to have global currentUser variable in Controller for Express using Passportjs?

I'm using the MEAN stack with passportjs for authentication. I know I can automatically pass currentUser to every view, through this code:
app.use(function(req, res, next){
res.locals.currentUser = req.user;
next();
});
However, I also would like to access currentUser throughout my controller, for certain database queries. For example, checking whether or not a user has liked a post, before sending the relevant information to the view. Is there a similarly easy way to access currentUser in all of my different routes/controller logic?
I know I can use req.user to get the user within the logic of a route. But ideally I don't have to do var currentUser = req.user at the top of each route's logic.
Thanks in advance for your help!!

Node Passport session lost on subsequent calls

I believe I have configured everything correctly:
app.configure(function() {
app.use(express.cookieParser('secret message')); // secret it set here in new version of express or connect
app.use(express.bodyParser());
app.use(express.session());
app.use(passport.initialize());
app.use(passport.session());
});
When the request is made to "login" with the correct credentials:
app.post('/api/login', passport.authenticate('local'), function (req, res, next) {
console.log(req.session.passport); // {"user":"5259f2739d4323000a000003"}
});
req.session.passport is populated:
"passport": {"user":"5259f2739d4323000a000003"}
However, when a call is made to:
app.post('/api/checklogin', function (req, res, next) {
console.log(req.session.passport); // {}
})
req.session.passport is lost:
"passport":{}
Both times, req.session looks like this:
{"cookie":{"originalMaxAge":null,"expires":null,"httpOnly":true,"path":"/"},"passport":{}}
** Passport object is obviously different though, as described above
I assume I have configured serializeUser correctly, because it correctly sets this property.
I am not completely sure how Passport creates session cookies, and how these cookies can persist.
I assume that req.session.passport is supposed to retain the user property, but it seems that the Passport object either:
Resets on every call
Does not actually save the Passport property in the session
The session is never created
I fear that I may be overlooking something large -- possibly something that I may need to do that Passport doesn't handle directly for me.
I do not know of any way to test if the session is created by Passport.
Any advice or help is really appreciated. This has been a multiple day struggle.
Are you using a cluster setup? If so, you need to stop using the default MemoryStore, and switch to something like connect-redis, so different instances of your app can access the shared session data.

redirect before loading URL

I'm developing a node.js app where I'm using passport to build OAuth authentication system. I can access the user through request object in each resource load after configurating it. But my question is: How can I do to check before every URL load - resources defined with app.get('/', function(..) {...}) - if user is loged and redirect the client if it's not loged. I could do it just adding a test in every method, but this is not what I want.
Thanks!
You want a middleware that checks whether the user is logged in.
isAuthenticated = function (req, res, next) {
if (req.user)
return next(); // All good, let the route handler process the request.
else
res.redirect('/login'); // Not logged in.
}
And to use it on every route that needs to be logged in:
app.get('/something', isAuthenticated, function (req, res) {
// Only in here if the user is authenticated.
});
You can also use the middleware on every route, by doing app.use(isAuthenticated), but you will need to have extra logic in the method to not create infinite redirect loops to /login, etc.

Resources