Skip a middleware and go to route - node.js

How to skip the middleware and go to the routes?
app.use(function(req, res, next) {
if (req.originalUrl === '/login') {
// How to skip the auth middleware and continue the routes?
??
}
next();
});
// auth middleware
app.use(acl.auth);
app.use('/', routes);

As they pointed out acl.auth will be fired for every request.
Why are you using two middlewares to check authentication?
req.body.user is not good. Save the user in request or in session.
Answering to your question, you can do something like that:
app.use(function(req, res, next) {
if (typeof req.user !== 'undefined') {
// Define a variable in request
req.isAuthenticated = true;
next();
}
next();
});
And in your acl.auth you can check that variable.
if(req.isAuthenticated) next();
EDIT
Also you can skip the middleware by not using app.use().
For example:
Routes with auth required:
app.get(acl.auth, function(req, res){});
Routes without auth required:
app.get(function(req, res){});

Related

Passport.js: how to protect ALL routes?

I followed the documentation for passport.js with passport-local: http://www.passportjs.org/docs/authorize/
When I send my users to /login they are authenticated, but nowhere in that document can I find how to authorise my users.
I've tried this, but that gives me a bad request:
router.get('/somepage', passport.authenticate('local'), function(req, res, next) {
});
I'm looking for way to protect all my pages at once. I'm working with Express 4.16 and use different route files to split up my routes.
Sam
you can use middleware with a small trick to switch between strategies
example:
const allowUrl = ['public', 'nonprivate','home'];
const authenticationMiddleware = (whiteList =[]) => (req, res, next) => {
if(whiteList.find(req.baseUrl)) {
next();
}
if (req.isAuthenticated()) {
return next()
}
res.redirect('/');
}
app = express();
app.use(passort.initialize());
app.use(authenticationMiddleware(allowUrl));
app.use(apiRouter);
app.listen(3000, ()=> console.log('hello internet');
you can add your middleware code like below
router.get('/', isAuthenticated, function(req, res) {
//your next function
});
function isAuthenticated(req, res, next) {
// do any checks you want to in here
// CHECK THE USER STORED IN SESSION FOR A CUSTOM VARIABLE
// you can do this however you want with whatever variables you set up
if (req.user.authenticated)
return next();
// IF A USER ISN'T LOGGED IN, THEN REDIRECT THEM SOMEWHERE
res.redirect('/');
}
As I wanted ALL routes (except for login routes off course) to pass authorization, I solved it as follows:
var ensureAuthenticated = function(req, res, next) {
if (req.isAuthenticated()) return next();
else res.redirect('/login')
}
// usersRouter contains all open routes like '/login':
app.use('/', usersRouter);
// From here on, all routes need authorization:
app.use(ensureAuthenticated);
app.use('/', indexRouter);
app.use('/api/foo', fooRouter);
app.use('/api/bar', barRouter);
I'm not sure what do you mean by "but nowhere in that document can I find how to authorise my users". Passportjs won't authorize any user. It is an authentication middleware. Authorization is different from authentication.
I think you are looking for application level middleware. You have to use app.use to make authentication work for each request to the server.
You can read more about it here. https://expressjs.com/en/guide/using-middleware.html#middleware.application

Is it possible to add an express middleware for a specific HTTP method?

I want add an Express middleware that must be triggered any time a POST request occurs (no matters the route URL).
I think that something like this should work:
app.use(function (req, res, next) {
if (req.method === 'POST') {
console.log('Time:', Date.now());
}
});
But I want to know if Express has something out of box to handle these scenarios.
Yes.
app.post(function (req, res, next) {
http://expressjs.com/api.html#router.METHOD
Not only is the previous answer correct, but you can also add middleware to specific routes as well, as in:
var addCustomField=function(req,res,next){ // assumes bodyparser
if('object'===typeof res.body){
res.body.myCustomField=true;
}
next();
};
app.post('/path',addCustomField,function(req,res){
// ...
});

Adding middleware after app.router

I have a server with the following defined :
app.get('/', function(req, res) {
// gets something
}
app.post('/', function(req, res) {
// updates something, need to be authenticated
}
Now I want the post action to be only for authenticated users, so I want to add a auth middleware between them like this :
app.get('/', function(req, res) {
// gets something
}
app.use('/', function(req, res) {
// check for authentication
}
app.post('/', function(req, res) {
// updates something, need to be authenticated
}
This way, GET gets through and for POST, user has to be authenticated.
The problem is that express doesn't go in to my app.use middleware. If i put the app.use middleware before all of the app.VERB routes, it works.
Is there any way to do it like I want ?
When you declare your first route, Express automatically inserts app.router into the middleware chain. Since the router gets to handle any following routes, any middleware that you declare after that first route will not get to handle your routes.
But instead of using app.use, you can use the fact that route-handlers are very similar to middleware:
app.get('/', function(req, res) {
// gets something
});
app.all('/', function(req, res, next) { // catches GET, POST, ... to '/'
// check for authentication
});
app.post('/', function(req, res) {
// updates something, need to be authenticated
});
But if you only have a single route that needs to be passed through the middleware, it makes sense to follow the advise of #hiattp and add the middleware to the route declaration immediately.
I like to put this type of check in a reuseable method and pass it into the route handler:
function ensureAuth(req, res, next){
if(req.user) next(); // Auth check
else res.redirect('/');
}
app.post('/', ensureAuth, function(req,res){
// User is authenticated
}

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.

Express.js: how to bypass Everyauth for certain routes?

I'm writing an application based on Express.js, while using Everyauth for authentication.
To initialize everyauth, I use:
app.use(everyauth.middleware());
I'd like to bypass authentication for certain routes.
Specifically, I noticed findUserById is called for every request, and I'd like to skip it for certain routes (e.g. no authentication for /getImage).
Is that possible?
You could wrap the everyauth.middleware() callback manually.
var auth = everyauth.middleware();
app.use(function(req, res, next) {
if (shouldAuthRequest(req)) {
// call auth, as if it was part of the route
auth(req, res, next);
} else {
// ignore auth
next();
}
});
This is nothing but a wrapped middleware.
As of 0.4.5, everyauth.middleware must be called with Express's app object. You can therefore create a wrapped middleware this way:
var my_auth_middleware = function(app) {
var auth = everyauth.middleware(app);
// a custom middleware wrapping everyauth
var middleware = function(req, res, next) {
if (shouldAuthRequest(req)) {
// go through the everyauth middleware
auth(req, res, next);
} else {
// bypass everyauth
next();
}
};
// these allow the middleware to be "mounted" by Express
middleware.set = true;
middleware.handle = middleware;
middleware.emit = auth.emit;
// return our custom middleware
return middleware;
};
and then add your wrapped middleware to the stack with
app.use(my_auth_middleware(app));

Resources