Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exclude route from express middleware

I have a node app sitting like a firewall/dispatcher in front of other micro services and it uses a middleware chain like below:

...
app.use app_lookup
app.use timestamp_validator
app.use request_body
app.use checksum_validator
app.use rateLimiter
app.use whitelist
app.use proxy
...

However for a particular GET route I want to skip all of them except rateLimiter and proxy. Is their a way to set a filter like a Rails before_filter using :except/:only?

like image 768
kreek Avatar asked Nov 25 '14 01:11

kreek


People also ask

How do I exclude a route from middleware?

To exclude a route from running an Express middleware, we can create our own function that accepts a route path and middleware function and returns a middleware function that checks the route path before running the middleware function.

Is a route handler middleware?

They are not middleware functions by definition. If such function is used on routing methods then they are only handler functions. We use such a handler function which is not a middleware when it is the only one callback function.

How do Middlewares work in Express?

Middleware literally means anything you put in the middle of one layer of the software and another. Express middleware are functions that execute during the lifecycle of a request to the Express server. Each middleware has access to the HTTP request and response for each route (or path) it's attached to.

What does exclude route from middleware mean?

Exclude a route from middleware prevent middleware from running defined express routes Thu, 03 Jan 2019 I had to implement this on one of my routes in a project that I’m currently working on. I use jwt tokens to make sure only authorized users can access my api and recently I needed to have a route that required no auth.

How to stop middleware from running on certain routes or request methods?

We can stop middleware from running on certain routes or request methods by using the express-unless package. To use it, we just set the unless function exposed from the package and set it to the unless property of our middleware function. Then we can exclude routes by using various conditions by checking the URL and/or request method.

How do I exclude calling the express static middleware from a request?

We can exclude calling the express.static middleware when we have the jpg , html , css or .js extensions as follows: In the code above, we check the extensions of the req.originalUrl property to see if they the request have the extensions listed in the array and skip the static middleware if they’re there.

How to skip middleware in express JS?

If we want to skip a middleware we can pass parameters to the middleware function and decide based on that parameter which middleware to call and which middleware to not call. express.js: To handle routing.


6 Answers

Even though there is no build-in middleware filter system in expressjs, you can achieve this in at least two ways.

First method is to mount all middlewares that you want to skip to a regular expression path than includes a negative lookup:

// Skip all middleware except rateLimiter and proxy when route is /example_route
app.use(/\/((?!example_route).)*/, app_lookup);
app.use(/\/((?!example_route).)*/, timestamp_validator);
app.use(/\/((?!example_route).)*/, request_body);
app.use(/\/((?!example_route).)*/, checksum_validator);
app.use(rateLimiter);
app.use(/\/((?!example_route).)*/, whitelist);
app.use(proxy);

Second method, probably more readable and cleaner one, is to wrap your middleware with a small helper function:

var unless = function(path, middleware) {
    return function(req, res, next) {
        if (path === req.path) {
            return next();
        } else {
            return middleware(req, res, next);
        }
    };
};

app.use(unless('/example_route', app_lookup));
app.use(unless('/example_route', timestamp_validator));
app.use(unless('/example_route', request_body));
app.use(unless('/example_route', checksum_validator));
app.use(rateLimiter);
app.use(unless('/example_route', whitelist));
app.use(proxy);

If you need more powerfull route matching than simple path === req.path you can use path-to-regexp module that is used internally by Express.

UPDATE :- In express 4.17 req.path returns only '/', so use req.baseUrl :

var unless = function(path, middleware) {
    return function(req, res, next) {
        if (path === req.baseUrl) {
            return next();
        } else {
            return middleware(req, res, next);
        }
    };
};
like image 119
lukaszfiszer Avatar answered Oct 11 '22 11:10

lukaszfiszer


Built upon the answer from @lukaszfiszer as I wanted more than one route excluded. You can add as many as you want here.

var unless = function(middleware, ...paths) {
  return function(req, res, next) {
    const pathCheck = paths.some(path => path === req.path);
    pathCheck ? next() : middleware(req, res, next);
  };
};

app.use(unless(redirectPage, "/user/login", "/user/register"));

Can't add as comment sorry.

like image 25
Geelie Avatar answered Oct 11 '22 09:10

Geelie


You can also skip route like this by putting a condition on req.originalUrl:

app.use(function (req, res, next) {

    if (req.originalUrl === '/api/login') {
    return next();
    } else {
         //DO SOMETHING
    }
like image 29
kj007 Avatar answered Oct 11 '22 10:10

kj007


I use this regular expression with success : /^\/(?!path1|pathn).*$/.

like image 33
Guillaume Avatar answered Oct 11 '22 10:10

Guillaume


There's a lot of good answers here. I needed a slightly different answer though.

I wanted to be able to exclude middleware from all HTTP PUT requests. So I created a more general version of the unless function that allows a predicate to be passed in:

function unless(pred, middleware) {
    return (req, res, next) => {
        if (pred(req)) {
            next(); // Skip this middleware.
        }
        else {
            middleware(req, res, next); // Allow this middleware.
        }
    }
}

Example usage:

app.use(unless(req => req.method === "PUT", bodyParser.json()));
like image 24
Ashley Davis Avatar answered Oct 11 '22 09:10

Ashley Davis


You can define some routes like below.

 app.use(/\/((?!route1|route2).)*/, (req, res, next) => {

    //A personal middleware
    //code

    next();//Will call the app.get(), app.post() or other
 });
like image 33
Guillaume Huard Hughes Avatar answered Oct 11 '22 11:10

Guillaume Huard Hughes