Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Express middleware only if route matches later

I want to have protected and unprotected routes, and make it so that a request to an undefined route will return a 404 even in the case that the user is unauthenticated. The problem I have is that the authentication middleware runs on all routes except those defined before it, so any undefined routes return an authentication failure instead of a 404. Here's an example of the problem:

var app = express();
var router = express.Router();

router.get('/', function(req, res) {
  res.send('unprotected route');
});

// best auth ever
router.use(function(req, res, next) {
  if(req.body.token) {
    return next();
  }

  res.send('auth failed');
});

router.get('/protected', function(req, res) {
  res.send('protected route');
});

/// catch 404
router.use(function(req, res) {
  res.sendStatus(404);
});

app.use('/', router);

In this case, a request without a token to a random route (e.g. /whatever) will return 'auth failed' rather than a 404. How do you resolve this in Express?

like image 219
zxcvb Avatar asked Sep 02 '15 16:09

zxcvb


1 Answers

One solution is to just move the authentication middleware into the route(s) before the route handlers:

// best auth ever
function checkAuth(req, res, next) {
  if(req.body.token) {
    return next();
  }

  res.send('auth failed');
}

router.get('/protected', checkAuth, function(req, res) {
  res.send('protected route');
});

You could even do this to a group of routes by defining all of the routes in a separate router and then doing something like router.use('/api', checkAuth, apiRouter).

Also, by default Express will respond with a 404 if no route matches, so you don't need to explicitly send it.

like image 200
mscdex Avatar answered Oct 19 '22 11:10

mscdex