Tomas
Tomas

Reputation: 2726

ExpressJS Applying middleware only to routes in router

I have app where I have public routes and authorized routes. Public routes should go through auth as well, but if auth fails, it doesn't matter.

So I have two routers:

var publicRoutes = express.Router();
var secretRoutes = express.Router();

publicRoutes
    .use(auth)
    .use(ignoreAuthError);

publicRoutes.get('/public', function(req, res){
    res.status(200).send({message: "public"});
}); 

secretRoutes
    .use(auth)
    .use(handleAuthError);

secretRoutes.get('/secret', function(req, res){
    res.status(200).send({message: "secret"});
}); 

...

app.use(publicRoutes);
app.use(secretRoutes);

Now everything works fine, but if I change the order of app.use public routes throw auth error. Also I cannot get any 404, 500 etc errors, because they all go through auth errors.

So obviously what is happening is that Router.use() is being applied to all routes with the same root - in this case "/"

Therefore I think if I would use just auth middleware on all routes and then add other middlewares directly to routes it should work fine. But it kind of brakes the point of having multiple Routers for me.

I would expect that if I use Router.use() the middleware will apply only if that particular router matches any routes it has set up, instead of changing behavior of other router.

Do I understand this correctly? Is there any way to handle this without actually having to add middleware to every single route?

Upvotes: 8

Views: 3189

Answers (1)

Pleymor
Pleymor

Reputation: 2921

Had the same issue, solved thanks to @Explosion Pills comment.

Bad:

app.use(secretRoutes); // router.use calls won't be scoped to "/secret" 
app.use(publicRoutes); // public routes will be impacted

Good:

app.use("/secret", secretRoutes); // router.use calls will be scoped to "/secret" 
app.use("/public", publicRoutes); // public routes won't be impacted

Upvotes: 4

Related Questions