Fange alle Routen AUSSER für / login

83

Ich schreibe derzeit eine API, bei der ein Benutzer ein Authentifizierungstoken im Header jeder Anforderung übergeben muss. Jetzt weiß ich, dass ich eine Sammelroute erstellen kann

app.get('/*', function(req,res){

});

aber ich habe mich gefragt, wie ich es so mache, dass bestimmte Routen wie /loginoder ausgeschlossen werden /?

clifford.duke
quelle
ZB Authentifizierung auf allen Routen außer / login und / register erforderlich . (Da sich die Leute fragen, warum Sie diese Frage gestellt haben)
a20

Antworten:

124

Ich bin nicht sicher, was passieren soll, wenn ein Benutzer auf /loginoder zugreift /, aber Sie können separate Routen für diese erstellen. Wenn Sie sie vor dem Catch-All deklarieren, erhalten sie erste Dibs bei der Bearbeitung der eingehenden Anforderungen:

app.get('/login', function(req, res) {
  ...
});

app.get('/', function(req, res) {
  ...
});

app.get('*', function(req, res) {
  ...
});
Robertklep
quelle
1
Dies würde nur für "GET" funktionieren, oder? Aus irgendeinem Grund kann ich diese Antwort nicht zum Arbeiten bringen app.use(um die anderen Methoden einzuschließen).
SSH Diesen
4
@SSHThis Ich denke, dass mit der neuesten Version von Express (v4) auch app.use('*', ...)funktionieren sollte. app.all('*', ...)In diesem Fall ist jedoch die Verwendung vorzuziehen.
Robertklep
@ JulienMartin gerade getestet, sieht aus wie es mit Express v4.16.3 funktioniert
Robertklep
app.useFügt Middleware hinzu, die die Anforderung standardmäßig an den nächsten Handler in der Kette weiterleitet (unter Verwendung eines zusätzlichen Arguments next).
Stijn de Witt
45

Sie können jederzeit eine Sammelroute nach den Routen platzieren, die Sie ausschließen möchten (siehe robertklep- Antwort).

Aber manchmal möchten Sie sich einfach nicht um die Reihenfolge Ihrer Routen kümmern. In diesem Fall können Sie immer noch tun, was Sie wollen:

app.get('*', function(req, res, next) {
  if (req.url === '/' || req.url === '/login') return next();
  ...
});
Leonid Beschastny
quelle
1
.get ('*', Funktion (req, res, next).
Oliver Dixon
2
@ iLoveUnicorns Danke! Warum hast du meinen Beitrag nicht einfach bearbeitet?
Leonid Beschastny
Wenn die anderen Regeln vorher sind, muss der nächste aufgerufen werden?
Sandburg
1
Die @ Sandburg-Middleware sollte entweder aufrufen next(), um die Ausführung an die nächste Middleware weiterzuleiten, oder eine Antwort senden, um die Verarbeitung der Anforderung abzuschließen . Andernfalls bleibt die Anfrage hängen. Wenn die letzte Middleware im Stack aufgerufen next()wird, sendet Express die Standardantwort "404 Not Found". Anstatt next()anzurufen , können Sie beispielsweise anrufen res.status(400).end(), um die Anforderungsverarbeitung mit einer Antwort "400 Bad Request" abzuschließen.
Leonid Beschastny
23

Wenn Sie Anmeldeinformationen oder Authentizität in jeder Anforderung überprüfen möchten, sollten Sie die Express-Routing-Funktion "all" verwenden. Sie können sie folgendermaßen verwenden:

app.all('/api/*', function(req, res, next){
    console.log('General Validations');
    next();
});

Sie können es vor jedem Routing-Material platzieren.

Beachten Sie, dass ich in diesem Fall "/ api / " als Pfad verwendet habe. Sie können "/ " verwenden, wenn es Ihren Anforderungen entspricht.

Ich hoffe, es ist nicht zu spät, hier jemandem zu helfen.

Seday Matzumiya
quelle
10

Eine andere Möglichkeit, einen Catch-All-Route-Handler zu erstellen, ist folgende:

app.get('/login', function(req, res) {
  //... login page
});
app.get('/', function(req, res) {
  //...index page
});
app.get('/:pageCalled', function(req, res) {
  console.log('retrieving page: ' + req.params.pageCalled);
  //... mypage.html
});

Dies funktioniert genau wie die (akzeptierte) Antwort von robertklep, bietet Ihnen jedoch weitere Informationen darüber, was der Benutzer tatsächlich angefordert hat. Sie haben jetzt einen Slug req.params.pageCalled, um die angeforderte Seite darzustellen, und können den Benutzer zur entsprechenden Seite weiterleiten, wenn Sie mehrere verschiedene Seiten haben.

Ein Gotchya, auf das Sie bei diesem Ansatz achten müssen (thx @agmin), /:pageCalledfängt nur Routen mit einer einzigen ab /, sodass Sie keine erhalten /route/1usw. Verwenden Sie zusätzliche Slugs wie /:pageCalled/:subPageCalledfür mehr Seiten (thx @softcode).

Jeremy Moritz
quelle
BESSER? "Ja wirklich?" Denken Sie nicht, dass die Umstände die Definition bestimmen? ;-) Unabhängig: Leute, die abstimmen, ohne einen Kommentar zu hinterlassen: Wie unhöflich!
Potherca
14
Es gibt eine riesige Gotchya mit diesem Ansatz, /:pageCalledwird nur Routen mit einer einzigen fangen /, so dass Sie nicht bekommen /route/1usw.
Agmin
Wenn Sie es nicht in einem Try / Catch umgeben, wird eine Fehlermeldung angezeigt, wenn diese Seite nicht vorhanden ist.
Darethas
@agmin also wäre die lösung nicht einfach hinzuzufügen /:pageCalled/:subPageCalledetc.?
Softcode