webentwicklung-frage-antwort-db.com.de

Route von der Express-Middleware ausschließen

Ich habe eine Knoten-App, die wie eine Firewall/ein Dispatcher vor anderen Micro-Services sitzt und eine Middleware-Kette wie unten verwendet:

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

Für eine bestimmte GET-Route möchte ich jedoch alle mit Ausnahme von rateLimiter und Proxy überspringen. Ist es eine Möglichkeit, einen Filter wie einen Rails vor_Filter zu setzen, mit: außer /: only?

20
kreek

Auch wenn es in expressjs kein integriertes Middleware-Filtersystem gibt, können Sie dies auf mindestens zwei Arten erreichen.

Die erste Methode ist das Mounten aller Middlewares, die Sie in einen regulären Ausdruckspfad überspringen möchten, als einen negativen 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);

Die zweite, wahrscheinlich lesbarere und sauberere Methode, besteht darin, Ihre Middleware mit einer kleinen Hilfsfunktion zu versehen:

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

Wenn Sie einen leistungsfähigeren Routenabgleich als einfachen path === req.path benötigen, können Sie das Pfad-zu-Regex-Modul verwenden, das intern von Express verwendet wird.

55
lukaszfiszer

Sie können die Route auch so überspringen, indem Sie eine Bedingung für req.originalUrl angeben:

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

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

Aufbauend auf der Antwort von @lukaszfiszer, da mehr als eine Route ausgeschlossen werden soll . Sie können hier beliebig viele hinzufügen.

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

Kann nicht als Kommentar hinzufügen.

4
Geelie

Ich benutze diesen regulären Ausdruck mit Erfolg: /^\/(?!path1|pathn).*$/.

4
Guillaume

Sie können einige Routen wie folgt definieren.

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

    //A personal middleware
    //code

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

Hier ist ein Beispiel für die Verwendung von path-to-regexp as @ lukaszfiszers Antwort lautet:

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
riscarrott