I wrote a JS script for a web server that includes authentication using passport and digest strategy. I do not use sessions, but I tried to use sessions, and this does not change the results. The browser asks for the "/ login" route and displays the built-in login dialog. Authentication works fine, but I can't get the user to "log out". The problem is that the browser remembers the login credentials and automatically redirects them. The end result is that the user must completely close the browser in order to log out, but this is a problem for this application. I know there must be a way to tell the browser not to do this, but I did not understand this.
I found out that the browser displays the login dialog again; make the authentication function return false. However, I did not understand the way to do this in a session. Right now, if one person logs out, everyone logs out. This is not an acceptable solution.
Can someone tell me what I'm doing wrong here? One thing I'm curious about is returning the correct answer to the browser when it is sent to the route / logout (see End). I am returning res.json (""), but maybe there is another answer I have to send in order to tell the browser to forget the credentials for the session?
My code follows. Any insight is greatly appreciated. Thank you in advance.
T
var passport = require('passport'), DigestStrategy = require('passport-http').DigestStrategy; var express = require('express'); var app = express(); app.configure(function () { app.use( "/", //the URL throught which you want to access to you static content express.static('./www') //where your static content is located in your filesystem ); app.use(express.cookieParser()); app.use(express.bodyParser()); app.use(express.session({ secret: 'keep moving forward' })); app.use(passport.initialize()); app.use(passport.session()); app.use(app.router); }); app.listen(80); //the port you want to use /** * CORS support. */ app.all('*', function(req, res, next){ if (!req.get('Origin')) return next(); // use "*" here to accept any origin // For specific domain, do similar: http://localhost' // Use an array for multiple domains, like [http://localhost', 'http://example.com' ] res.set('Access-Control-Allow-Origin', '*' ); res.set('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE'); res.set('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type, Authorization'); next(); }); // // Configure passport authentication // // Used to force the browser to display the login screen again. var forceLogin = false; passport.use(new DigestStrategy({ qop: 'auth' }, function(username, done ) { if ( !forceLogin ) { return done(null, username, "nimda"); } else { // // Forces the browser to request the user name again by returning a failure to its last request. // console.log ( "forcing user to log in" ); forceLogin = false; return done(null, false); } )); passport.serializeUser(function(user, done) { console.log( "serialize user " + user.toString() ); done(null, user.toString()); }); passport.deserializeUser(function(id, done) { console.log( "deserialize user " + id.toString() ); done(null, id); }); app.post('/login', passport.authenticate('digest', { session: true }), function(req, res) { console.log( "/login"); res.header('Cache-Control', 'no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0'); res.json({ id: req.user.id, username: req.user.username }); }); app.post('/logout', function(req, res){ req.logOut(); // NOTE: Same results as req.logout // // req.session.destroy(function (err) { // res.redirect('/'); // }); res.redirect("/"); // flag to force a login forceLogin = true; console.log( "logout"); // Is this the proper return to the browser? return res.json(""); });