Exclude route from express middleware

前端 未结 8 1578
被撕碎了的回忆
被撕碎了的回忆 2020-12-05 02:40

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.u         


        
相关标签:
8条回答
  • 2020-12-05 03:21

    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);
            }
        };
    };
    
    0 讨论(0)
  • 2020-12-05 03:26

    Here's an example of using path-to-regexp as @lukaszfiszer's answer suggests:

    import { RequestHandler } from 'express';
    import pathToRegexp from 'path-to-regexp';
    
    const unless = (
      paths: pathToRegexp.Path,
      middleware: RequestHandler
    ): RequestHandler => {
      const regex = pathToRegexp(paths);
      return (req, res, next) =>
        regex.exec(req.url) ? next() : middleware(req, res, next);
    };
    
    export default unless;
    
    
    0 讨论(0)
  • 2020-12-05 03:27

    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.

    0 讨论(0)
  • 2020-12-05 03:32

    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
     });
    
    0 讨论(0)
  • 2020-12-05 03:35

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

    0 讨论(0)
  • 2020-12-05 03:35

    The way I achieved this is by setting up a middleware for a specific path like so

    app.use("/routeNeedingAllMiddleware", middleware1);
    app.use("/routeNeedingAllMiddleware", middleware2);
    app.use("/routeNeedingAllMiddleware", middleware3);
    app.use("/routeNeedingAllMiddleware", middleware4);
    

    and then setting up my routes like so

    app.post("/routeNeedingAllMiddleware/route1", route1Handler);
    app.post("/routeNeedingAllMiddleware/route2", route2Handler);
    

    For the other special route that doesn't need all the middleware, we setup another route like so

    app.use("/routeNeedingSomeMiddleware", middleware2);
    app.use("/routeNeedingSomeMiddleware", middleware4);
    

    and then setting up the corresponding route like so

    app.post("/routeNeedingSomeMiddleware/specialRoute", specialRouteHandler);
    

    The Express documentation for this is available here

    0 讨论(0)
提交回复
热议问题