2

I want to implement an authentication logic similar to the asp.net mvc's allowanonymous attribute.

In node app I have code like this

var authChecker = function(req, res, next){
if (req.session.user 
    && req.session.user.loggedIn) {
    next();
}
else {
    res.redirect('/login');
}   
}
app.use(authChecker);

//this path should be allowed for anonymous access
app.get('/public', function(req, res) { 

});

//this path is checked globally
app.get('/private', function(req, res) { 

});

but I chould'nt figure out how to create a filter for the paths that I want to make accessible with out login...

How can I do that?

4 Answers 4

0

Rather than useing authChecker globally, just use it in each route you want to protect.

var authChecker = function(req, res, next){
if (req.session.user 
    && req.session.user.loggedIn) {
    next();
}
else {
    res.redirect('/login');
}   
}


//this path should be allowed for anonymous access
app.get('/public', function(req, res) { 

});

//this path is checked globally
app.get('/private', authChecker, function(req, res) { 

});
2
  • the security best practice says that we should make all the app private and just bypass authorization for the necassary pages...
    – Serdar
    Nov 2, 2013 at 18:27
  • 3
    a developer may forget to add authchecker it is a problem, but if someone forgets to add bypassautorization or allowanonymous thing it is not a problem...
    – Serdar
    Nov 2, 2013 at 18:27
0

want to implement an authentication logic similar to the ... allowanonymous attribute.

Modify AuthChecker so that it can recieve an optional configuration object.

const authcheck = (options={}) => {
  return (req, res, next) => {
    //...........
    if (options.allowAnonymous === True) {
      next();
    }
    //............
  };
};

app.get('/', authCheck({allowAnonymous: True}), (req, res) => {
  // ................
});
New contributor
Koza is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
2
  • If I need to attach the authCheck to every route with different options, there is no need for additional options. Then you could just not add the authcheck to routes where you don't need it. 2 days ago
  • this answer is only an alternative that allows options to be set per path as per OPs requirements, its not my chosen approach, see my other answer for what i would choose. if paths need per path options. the other answer is still prefferable because we can just process them in the authcheck function.
    – Koza
    yesterday
0

There are a few ways to achieve this.

The simplest probably is, not to attach the authChecker globally, but with each request. This of course, bears the risk, of a dev, forgetting to include the authChecker in a request that should be protected.

app.get("/nologin", nologinhandler);
app.get("/withlogin", authChecker, withloginhandler);

Another way exploits the fact, that the order in which you attach routes and middlewares to your app is important. Ie, if you do something like this

app.get("/nologin", nologinhanlder);
app.get("/req1", ...);
app.get("/req2", ...);


//all requests above this line won't require authenication
app.use(authChecker);
//all requests following this line will require authentication

app.get("/withlogin", withloginhandler);

the all routes created before the app.use(authChecker); will in fact not go through the authChecker middleware, whereas all requests attached after app.use(authChecker); will have to pass the authChecker. Of course this is still not 100% failsafe, as devs can add new routes whereever they want. But it seems to be easier to handle than rembering to add auth to every single request. Of course, this might also lead to some problems, because the route matching in express also happens in the order the routes are added, and in some cases, similar routes have to be added in a certain order, to be correctly matched.

You could also use two differernt routers to make this even more explicit

let authrouter = express.Router();
let noauthrouter = express.Router();

authrouter.use(authChecker);
authrouter.get("/withlogin", ...);

noauthrouter.get("/nologin", ...);

app.use(noauthrouter);
app.use(authrouter);

So it's clear, that when a request is attached to the noauth router, it doesn't require authentication, whereas when it's attachted to the auth router, it does. Again, it's important here, to attach the noauthrouter to the app first ...

A third possibility is of course, checking the path within the authChecker. Ie something like this

function canAnonymous(path) {
  if (path === "/nologin")
    return true;

  //any other checks for other paths
  ... 

  return false;
}

function authChecker(req, res, next) {
  if (canAnonymous(req.path))
    return next();

  //do default authcheck
  ... 
}

app.use(authChecker);
app.get("/nologin", nologinhandler);
app.get("/withlogin", withloginhandler);

This way, all requests will go through the authChecker, and without being added as an exception, the will also need authentication. Ie making them accessible for anonymous requires additional work. Of course, matching such path can be complicated if you for instance have path parameters or optional parts.

0

req.originalUrl

this simple solution avoids redundant function names when you have dozens of paths.

all paths from every request will be processed.


how to create a filter for the paths that I want to make accessible with out login...

you can use req.originalUrl to get the requested path, and filter accordingly.

const privatePaths = ['/path1','/path2'..........]

const authChecker = function(req, res, next){
  // if requested path begins with a private path

  if (privatePaths.some(privatePath => req.originalUrl.startsWith(privatePath))) {
    // this is a private path, check credentials.
    ........

  } else {
    // this is a public path, allow the request.
    next();
  } 
}

app.use(authChecker);

app.get('/Every/Path/Will/Be/Checked', function(req,res){
  .........
})

a developer may forget to add authchecker it is a problem, but if someone forgets to add bypassautorization or allowanonymous thing it is not a problem...

All paths of EVERY request will be checked, there is no need to include the middleware to any individual path.


New contributor
Koza is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.