allow access to html page only to logged in users - node.js

I have app.html in a public folder which is serving static files to express.
I have used code from here.
But instead of profile.ejs from views folder(as per the code in link), I want to serve app.html from inside of public folder.
app.get('/app.html', isLoggedIn, function(req, res) {
res.render('app.html'/*, {
user : req.user // get the user out of session and pass to template
}*/);
console.log("APP.HTML");
});
function isLoggedIn(req, res, next) {
// if user is authenticated in the session, carry on
if (req.isAuthenticated())
return next();
// if they aren't redirect them to the home page
res.redirect('/');
}
But it does not restrict the access to loggedIn users and I am able to access it directly after logging out as well.
What could be wrong here?

The problem is most likely that you have express.static() before your app.get() line. The static middleware checks if the file exists and sends it if it does. So you need to put that app.get() before your express.static() middleware.

Related

Stop duplication of passportjs isAuthenticated code in Express route files

I am using passportjs for my authentication.
I have lots of different routes throughout the project, 95% of them require the following function:
// Middleware functions
function isAuthenticated(req, res, next) {
if (req.isAuthenticated())
return next();
res.redirect('/login');
}
At the moment, I am putting this function at the bottom of EVERY route file.
Is there a way to write it once, and be able to use it in all the route files?
If you add that middleware before the routes that require it, all requests will pass through it before they get forwarded to the correct route handler:
// doesn't require an authenticated request
app.use(router1);
// add the middleware just once
app.use(isAuthenticated);
// all following route(r)s require an authenticated request
app.use(router2);
app.use(router3);
...

Node Express - res.redirect() not behaving as expected

I am trying to redirect to a login page after successfully logging a user out, but am having an issue when calling res.redirect() from my logout route handler in express.
I have the following middleware to redirect a user to a login page (note I am using express-session too)
//A request to '/login' will serve the login page
app.use('/login', function(req, res){
res.sendFile(path.join(__dirname+'/public/login.html'))
});
//This will listen for all requests
app.use(function(req, res, next) {
//Here we only want to redirect to the logic route (above) if the request is not
//a login action and there is no access token present on the session object
if (req.url!== '/auth/login' && !req.session.accessToken) {
res.redirect('/login');
} else {
next();
}
});
This redirect above works as expected.
When a user performs a logout, I handle like so:
app.post('/auth/logout', function(req, res){
req.session.destroy();
res.redirect('/login');
});
I can see in Chrome debugger, the network tab shows my login view is being served back to the browser, but the browser window does not change. I notice the login.html is being returned with a 304 code too if that has any relevance. I'm feeling a bit dumb but am failing to see what's different here, can someone shed some light please?
Thanks

Always pass variable to Express res.render

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.

Express routes passing data to view

I have data that I am able to log to the console but can't figure out how to make it available to my view.
The following works to console.log req.user upon signing in to an admin page
app.use(function(req, res, next){
console.log(req.user);
next();
});
The entire JSON object is passed into the console. I'd like to be able to pass it into my view but can't seem to make the following logic work. I'm either not passing it into the route correctly or not pulling it out into ejs correctly.
app.get('/', function(req, res) {
res.render('index.ejs',{
bootstrappedUser: req.user
});
});
What version of express are you using?, I dont see error in your code , but maybe in config files.Are you setting app.set('view engine','ejs')?,maybe your index.ejs file is not in the correct folder so you need to move it to /views in the root folder of your application.

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