2015-04-07 7 views
10

Ich mag würde einen Antwortcode von 401 zu senden, wenn der anfragende Benutzer nicht authentifiziert ist, aber ich würde auch gerne umleiten, wenn die Anforderung war ein HTML anfordern. Ich habe festgestellt, dass Express 4 dies nicht zulässt:Chaining Express.js 4 der res.status (401) zu einer Umleitung

res.status(401).redirect('/login') 

Kennt jemand eine Möglichkeit, dies zu umgehen? Dies ist möglicherweise keine Einschränkung von Express, da ich im Wesentlichen zwei Header übergebe, aber ich sehe nicht, warum das der Fall sein sollte. Ich sollte in der Lage sein, eine "nicht authentifizierte" Antwort zu übergeben und den Benutzer auf einmal umzuleiten.

+0

Ich habe auch bemerkt, Express-Weiterleitungen POST zu GET, die mich überrascht – Plato

+2

Nur eine kurze Anmerkung: Wenn das Asset mit Authentifizierung zugegriffen werden kann der Statuscode 401. Wenn es vollständig mit oder ohne Authentifizierung der Statuscode ist verboten sei 403. –

+1

@brockangelo Ixe Antwort ist die einzige Möglichkeit, wie ich das (manuell .set(), dann .send()) tun kann. Aber ich denke, die größere Frage ist, ob Sie wirklich eine 401 senden möchten, wenn Sie eine Weiterleitung planen. Sehen Sie sich den SO-Link in meinem Kommentar zu Jasons Antwort –

Antwort

12

einen neuen Standort Header einige subtile diferences mit den Methoden gibt es für das Versenden zurück.

Mit redirect:

app.get('/foobar', function (req, res) { 
    res.redirect(401, '/foo'); 
}); 
// Responds with 
HTTP/1.1 401 Unauthorized 
X-Powered-By: Express 
Location: /foo 
Vary: Accept 
Content-Type: text/plain; charset=utf-8 
Content-Length: 33 
Date: Tue, 07 Apr 2015 01:25:17 GMT 
Connection: keep-alive 

Unauthorized. Redirecting to /foo 

Mit status und location:

app.get('/foobar', function (req, res) { 
    res.status(401).location('/foo').end(); 
}); 
// Responds with 
HTTP/1.1 401 Unauthorized 
X-Powered-By: Express 
Location: /foo 
Date: Tue, 07 Apr 2015 01:30:45 GMT 
Connection: keep-alive 
Transfer-Encoding: chunked 

Mit dem Original (falschen) Ansatz redirect:

app.get('/foobar', function (req, res) { 
    res.status(401).redirect('/foo')(); 
}); 
// Responds with 
HTTP/1.1 302 Moved Temporarily 
X-Powered-By: Express 
Location: /foo 
Vary: Accept 
Content-Type: text/plain; charset=utf-8 
Content-Length: 38 
Date: Tue, 07 Apr 2015 01:26:38 GMT 
Connection: keep-alive 

Moved Temporarily. Redirecting to /foo 

So sieht es aus wie redirect Gibt alle vorherigen Statuscodes zurück und sendet den Standardwert (sofern nicht im Methodenaufruf angegeben). Dies ist aufgrund der Verwendung von Middleware innerhalb von Express sinnvoll. Wenn Sie eine globale Middleware hätten, die Vorabprüfungen für alle Anfragen durchführt (wie zum Beispiel nach den richtigen Übernahmeköpfen usw.), wissen sie nicht, dass sie eine Anfrage umleiten müssen. Allerdings würde die Authentifizierungs-Middleware es und somit wissen, alle vorherigen Einstellungen zu überschreiben, um sie richtig einzustellen.

UPDATE: Wie in den Kommentaren unten angegeben, dass, obwohl Express einen 4XX- Statuscode mit einem Location-Header gemäß den Spezifikationen zu verstehen, bedeutet nicht senden kann es sich um eine akzeptable Antwort auf eine Anfrage Client ist. Tatsächlich ignorieren die meisten den Location-Header, außer der Statuscode ist ein 3XX-Wert.

+0

an, dieser beantwortet ihn (teilweise). 'Umleitung werden alle vorherigen Statuscodes verlassen und den Standardwert' senden - beachten Sie die [docs hier] (http://expressjs.com/api.html#res.redirect) „Wenn Sie nicht über Status angeben, wird der Statuscode Standardeinstellung ist "302" Gefunden "". Beachten Sie jedoch, dass die Redirect-Funktion nur für den Bereich 300 funktioniert. gibt es auf diese eine vorherige hier SO - http://stackoverflow.com/questions/21519094/why-doesnt-express-redirect-properly-when-i-edit-the-status-code –

+0

@JustinMaat vereinbart, dass die allgemeine Verwendung von Das ist falsch.401 sollte an den Anforderer zurückgeschickt werden, damit sie wissen, dass sie mit der richtigen Authentifizierungsmethode erneut anfordern sollte über die [ 'WWW-Authenticate'] (http://en.wikipedia.org/wiki/List_of_HTTP_status_codes#4xx_Client_Error) Header angegeben. Dies ist normalerweise ein Token oder eine Basisberechtigung. Meine Antwort war zu zeigen, dass Express * kann es tun, aber nicht, dass es richtig ist. Aktualisieren meiner Antwort, um dies zu reflektieren. –

3

Sie können sicherlich senden Sie eine Location: /login Header neben Ihrer 401 Seite, jedoch ist dies nicht ratsam, und die meisten Browser werden nicht folgen, wie per rfc2616.

Eine Möglichkeit, dies zu tun zu überwinden, ist <meta http-equiv="refresh" content="0; url=/login"> neben mit Ihrem 401 Seite zu dienen:

res.set('Content-Type', 'text/html'); 
res.status(401).send('<!DOCTYPE html><html><head><meta http-equiv="refresh" content="0; url=/login"></head></html>`);