2013-05-03 11 views
10

Ich versuche, einen Web-Server mit Express einzurichten. Um auf diesen Server zugreifen zu können, müssen sich die Benutzer authentifizieren. Dafür verwende ich die von Express bereitgestellte basicAuth() Middleware. Es funktioniert perfekt, außer dass ich mich nicht ausloggen kann, sobald ich mich eingeloggt habe! Ich muss meinen Browser schließen, um die Verbindung zu trennen, aber stattdessen möchte ich eine "Disconnect" -Seite haben, die auf die "Login" -Seite umleiten würde (diese mit dem abscheulichen Formular, mit dem man sich anmeldet ...).Ausloggen von basicAuth (Express)

Hat jemand eine Idee?

Dank pro Voraus

PS: HTTP-Basic-Authentifizierung, deren Implementierung benötigt keine HTML-Seiten, Cookies noch Session-IDs Ich entschuldige mich für meine pathetische Englisch :)

+0

[Dieser Stackoverflow] (http://stackoverflow.com/questions/7990890/how-to-implement-login-auth -in-node-js) Frage hat ein Abmeldungsbeispiel Die einfachste Antwort lautet "Aktualisiere die req.session-Variable beim Abmelden". –

+0

werfen Sie einen Blick auf den Pass http://passportjs.org/ Modul zusammen mit Pass-lokalen https://github.com/jaredhanson/passport-local. Es erleichtert das Abmelden durch Aufruf von req.logout(). Passport macht es auch leicht, andere Authentifizierungsmethoden in der Zukunft hinzuzufügen, wenn Sie wollen – Noah

Antwort

21

Express' BasicAuth verwendet. Seine Hauptnachteile sind, dass es nicht sicher ist und, unser Interesse hier, gibt es keinen Mechanismus in der Spezifikation für den Server, um den Browser anzuweisen, sich abzumelden.

express.basicAuth() -Aufrufe erfordern (blah-blah/connect/lib/utils) .unauthorized() sendet einen 401-Status mit Header 'WWW-Authenticate: Basic realm = "..."'. Der Browser behandelt das Authentifizierungsfenster und fortan sendet einen Header wie 'Autorisierung: Basic YmFzaWM6YmFzaWM =', die den Benutzernamen und das Passwort enthält.

(express.basicAuth ist nicht sicher, vor allem über HTTP, weil Sie den Benutzernamen bekommen: Passwort mit

new Buffer('YmFzaWM6YmFzaWM=' , 'base64').toString() 

die Grund gibt. In diesem Fall basic)

Unser Problem ist die Die HTTP-Spezifikation bietet keine Möglichkeit, den gesendeten Header zu stoppen. Eine Umgehung für HTTPS besteht darin, den Benutzer an eine URL in derselben Domäne mit falschen Anmeldeinformationen umzuleiten.

Die HTTP-Problemumgehung, die ich für Express V3 verwende, kann mit app.use (express.basicAuth (...)) verwendet werden. Ich finde es einfacher zu verwenden als andere Lösungen, die einen Aufruf von Middleware in jeder gesicherten Route erfordern, z. app.get ('/ secure', checkAuth, function (req, res) {...}).

Hier ist ein Arbeitsbeispiel.

var express = require('express'), 
    http = require('http'), 
    app = express(); 

app.use(express.favicon()); // prevent interference during test 
app.use(express.bodyParser()); 
app.use(express.cookieParser()); 
app.use(express.session({ secret: 'winter is coming' })); 

app.use(function (req, res, next) { 
    if (!req.session.authStatus || 'loggedOut' === req.session.authStatus) { 
    req.session.authStatus = 'loggingIn'; 

    // cause Express to issue 401 status so browser asks for authentication 
    req.user = false; 
    req.remoteUser = false; 
    if (req.headers && req.headers.authorization) { delete req.headers.authorization; } 
    } 
    next(); 
}); 
app.use(express.basicAuth(function(user, pass, callback) { 
    callback(null, user === 'basic' && pass === 'basic'); 
}, '***** Enter user= basic & password= basic')); 
app.use(function (req, res, next) { 
    req.session.authStatus = 'loggedIn'; 
    next(); 
}); 

app.use(app.router); 
app.get('/secure', function (req, res) { 
    res.send([ 
    'You are on a secured page.', 
    '<br>', 
    '<a href="./secure">Refresh this page without having to log in again.</a>', 
    '&lt;br/>', 
    '<a href="./logout">Log out.</a>' 
    ].join('')); 
}); 
app.get('/logout', function (req, res) { 
    delete req.session.authStatus; 
    res.send([ 
    'You are now logged out.', 
    '&lt;br/>', 
    '<a href="./secure">Return to the secure page. You will have to log in again.</a>', 
    ].join('')); 
}); 

http.createServer(app).listen(3000, function(){ 
    console.log('Express server listening on port 3000. Point browser to route /secure'); 
}); 

P.S. Dein Englisch ist ausgezeichnet.

+0

Hey, schnelle Frage, was macht die nächste(); Funktion tun? –

+0

http://stackoverflow.com/questions/10695629/node-js-express-next – Domenic

10

Für Express.js 4 und BasicAuth, können Sie diese Methode verwenden:

app.get('/logout', function (req, res) { 
    res.set('WWW-Authenticate', 'Basic realm=Authorization Required'); 
    return res.sendStatus(401); 
});