How to intercept each and every req in express framework - node.js

I am looking to check user is authenticated or not before they browse something for that I have written this code.
router.use(function (req, res, next) {
console.log(req);
if(req.isAuthenticated()){
console.log("if......");
return next();
}else{
if (req.url === '/users/login' || req.url === '/users/register'){
console.log("if......2");
return next();
}else{
if (req.url === '/'){
console.log("if......3");
res.redirect('/users/register');
}else{
res.redirect('/users/login');
}
}
}
});
Now I have two questions to clear.
Is this the standard way to do this? No, please let me know how to achieve.
whenever I browse localhost:3000 my req.url = /user/login I am surprised with that too. I don't know how its even possible.
But may be cache or something not sure to clear this I must inform, Before that I had code some thing like below which was meant to intercept or validate user when he hits localhost:3000 but now I have commented that entire code.
// Get Homepage
router.get('/'/*, ensureAuthenticated*/, function(req,res){
res.render('index');
});
/*function ensureAuthenticated(req, res, next){
if(req.isAuthenticated()){
return next();
}else{
res.redirect('/users/login');
}
}
router.use(function (req, res, next) {
console.log('Time:', Date.now());
next();
});*/

middleware come in handy here.
define your middleware like
module.exports.isAuthenticated=function(req,res,next){
if(req.isAuthenticated){
return next();
}
next(error('user is not authorized'));
}
then in your route file
route.get('/home',auth.isAutheticated,goToHome);

Related

How do Allow only Admins to have access to the Admin page in Nodejs `AdminBro`

How do Allow only Admins to have access to the Admin page in AdminBro? Nodejs
All that I want is for only Admins to have access to the adminBro page, is there any specific method to get this done?
I did this in my app.js file but it's not working
app.get("/admin", function (req, res, next) {
res.locals.login = req.user;
if (res.locals.login.roles == "admin") {
app.use("/admin", adminRouter);
} else {
res.redirect("/");
}
});
You cannot use new app.use inside app.get, as (req, res, next) are already consumed. You have two of choice:
Your route in if condition body
if (res.locals.login.roles === 'admin') {
// your admin route logic
res.send('admin page')
} else {
res.redirect('/')
}
I'm used to use small middleware function like this one:
const isAdmin = (req, res, next) => {
if (req.user.roles === 'admin') {
return next();
}
res.redirect('/');
};
Then you use it in whichever route this way:
app.get('/admin', isAdmin, adminRouter)

Second middleware is only called after the route method

I have 2 middleware , one that check if the user has a valid token and the second one that check if the user has permissions. The probleme is that after calling the first middleware the program is going directly inside my route method instead of calling the 2nd middleware. Here my code :
app.use(function(req, res, next) {
checkToken(req, res, next);
checkPermission(req, res, next);
});
app.post("/test", (req, res) => {
console.log("route");
})
function checkToken(req, res, next){
console.log("check token");
if(validToken())
next();
else
res.send("no valid token");
}
function checkPermission(req, res, next){
console.log("check permission");
if(permission())
next();
else
res.send("no permission");
}
Output I get:
check token -> route -> check permission
Output that I expect :
check token -> check permission -> route
What I want my program to do is to check either if the user has a valid token and if he has permission before going inside my route method!
Is this the right way to do it ?
app.use(checkToken);
app.use(checkPermission);
app.post("/test", (req, res) => {
console.log("route");
});
...
Each express middleware is given one next callback to trigger the next middleware, but here you are calling two functions inside the middleware which calls next in each method. You have to refactor your code like this,
app.use(checkToken); // <== first middleware
app.use(checkPermission) // <== Second middleware
app.post("/test", (req, res) => {
console.log("route");
})
function checkToken(req, res, next) {
console.log("check token");
if (validToken())
next();
else
res.send("no valid token");
}
function checkPermission(req, res, next) {
console.log("check permission");
if (permission())
next();
else
res.send("no permission");
}
See also Writing middleware for use in Express apps for a better understanding how middleware work.
/* Check token */
function checkToken(req, res, next) {
console.log("check token");
if(validToken())
next();
else
res.send("no valid token");
}
/* Check permission */
function checkPermission(req, res, next) {
console.log("check permission");
if(permission())
next();
else
res.send("no permission");
}
/* Calling the middleware in right order */
app.use(checkToken, checkPermission, (req, res, next) => {
next();
});
/* Finally our route */
app.post("/test", (req, res) => {
console.log("route");
});

How to to create a custom logger in Express?

During an exercise in school we have been tasked with making custom middleware in Express:
This might be tricky. Make it so that your custom logging middleware
also logs out the eventual response status code. For example, after a
successful GET request to / you should see:
GET / 200
I tried this:
app.use(function(req, res, next) {
console.log(chalk.green(req.method, req.url, res.statusCode));
next();
});
It appears to work but then I noticed upon trying a uri which doesn't exist I still get:
GET /foo 200
Does this mean the request i.e. GET, is working but has nothing to do if the resource is there?
Also how would I implement error handling, in this instance I tried:
app.use(function(err, req, res, next) {
if (err) {
console.log(err);
} else {
console.log(chalk.green(req.method, req.url, res.statusCode));
}
next();
});
But that didn't work at all!
Thanks in advance!
app.use(function(req, res, next) {
if (res.headersSent) {
console.log(chalk.green(req.method, req.url, res.statusCode));
} else {
res.on('finish', function() {
console.log(chalk.green(req.method, req.url, res.statusCode));
})
}
next();
});

How to call Connect middleware directly?

I have a express route like this:
app.get('/', auth.authOrDie, function(req, res) {
res.send();
});
where authOrDie function is defined like that (in my auth.js module):
exports.authOrDie = function(req, res, next) {
if (req.isAuthenticated()) {
return next();
} else {
res.send(403);
}
});
Now, when the user is not authenticated, I would like to verify if the http request has a Authorization (Basic) header. To do that, I would like to use the great connect middleware basicAuth().
As you know, Express is built on top of Connect, so I can use express.basicAuth.
The basicAuth is generally used like that:
app.get('/', express.basicAuth(function(username, password) {
// username && password verification...
}), function(req, res) {
res.send();
});
But, I would like to use it in my authOrDie function like that:
exports.authOrDie = function(req, res, next) {
if (req.isAuthenticated()) {
return next();
} else if {
// express.basicAuth ??? ******
} else {
res.send(403);
}
});
****** How can I call the basicAuth function with the good parameters (req ? res ? next ? ...).
Thanks.
Calling the express.basicAuth function returns the middleware function to call, so you'd invoke it directly like this:
exports.authOrDie = function(req, res, next) {
if (req.isAuthenticated()) {
return next();
} else {
return express.basicAuth(function(username, password) {
// username && password verification...
})(req, res, next);
}
});

Node routes for authenticated area?

We have an app with the following routes
/dothis/
...//dothis routes
/dothat
...//dothat routes
/doother
...//doother routes
and a login route:
/login
and
/ //which currently actually isn't even used, would redirect to /login
Is it possible to close the routes so that actually only / and /login are accessible without authentication? Or do we need to apply a prefix to all other routes. Thanks
app.get('*', function(req, res, next) {
// console.log(everyauth);
if (!req.session.auth) {
res.redirect('/login');
} else {
next();
}
});
app.get('/login', function(req, res){
res.render('login', {
});
});
seems to work
app.all('*', Authentication, function(req, res) {
});
function Authentication(req, res, next) {
if (req is not user) {
if (req.url === '/' || req.url === '/login')
next()
}
else
next();
}
I have middleware which does exactly this: https://github.com/jaredhanson/connect-ensure-login
app.get('/dothat',
ensureLoggedIn('/login'), // redirect to /login if not logged in
function(req, res) {
// render do that;
});
It's usable stand-alone, but also integrates seamlessly with Passport, so that after login, the user will be redirected back to the URL they originally requested.

Resources