web-dev-qa-db-fra.com

Exclure la route du middleware express

J'ai une application de noeud assise comme un pare-feu/répartiteur devant d'autres micro services et elle utilise une chaîne de middleware comme ci-dessous:

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

Toutefois, pour un itinéraire GET particulier, je souhaite les ignorer tous sauf rateLimiter et le proxy. Est-ce un moyen de définir un filtre comme un Rails before_filter en utilisant: except// only?

20
kreek

Même s'il n'y a pas de système de filtrage middleware intégré dans expressjs, vous pouvez y parvenir d'au moins deux manières.

La première méthode consiste à monter tous les middlewares que vous souhaitez ignorer sur un chemin d’expression régulière qui inclut une recherche négative:

// 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);

La deuxième méthode, probablement plus lisible et plus propre, consiste à envelopper votre middleware avec une petite fonction d’aide:

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);

Si vous avez besoin d'une correspondance de route plus puissante que le simple path === req.path, vous pouvez utiliser le module chemin-à-regexp utilisé en interne par Express.

55
lukaszfiszer

Vous pouvez également ignorer un itinéraire comme ceci en mettant une condition sur req.originalUrl:

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

    if (req.originalUrl === '/api/login') {
    return next();
    } else {
         //DO SOMETHING
    }
10
kj007

Construit sur la réponse de @lukaszfiszer car je voulais exclure plusieurs itinéraires ..__, vous pouvez en ajouter autant que vous le souhaitez ici.

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"));

Impossible d'ajouter comme commentaire désolé.

4
Geelie

J'utilise cette expression régulière avec succès: /^\/(?!path1|pathn).*$/.

4
Guillaume

Vous pouvez définir des itinéraires comme ci-dessous.

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

    //A personal middleware
    //code

    next();//Will call the app.get(), app.post() or other
 });