Node.Js + express + Passport: cannot log out

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(""); }); 
+6
source share
4 answers

You can try the following

 req.session.destroy() req.logout() res.redirect('/') 

Maintaining a new session state is important if you use some form of session storage for persistent sessions (like Redis). I tried the above code with a similar setup and it seems to work for me

+6
source

The server needs to somehow notify the web browser that it needs to update the login information (MD5 digests). To do this, you can send an error code 401, and usually the browser will display a pop-up message to enter.

By the way, all these tricks with sessions are useless, because the browser already has all the necessary information for automatic login.

So you can try the following code:

 req.logout(); res.send("logged out", 401); 
+4
source

A bit late for the party, but I found this thread on Google when I was looking for an answer, and nothing worked for me. Finally, I was able to solve it, so I thought that I could publish the solution here for anyone who could read this in the future.


Basically, I use node.js, express, passport (local) and rethinkdb as my repository, and I am having a problem with req.logout(); Do not log me out of the system.

My setup:

 var express = require( 'express' ); var passport = require( 'passport' ); var session = require( 'express-session' ); var RDBStore = require( 'express-session-rethinkdb' )( session ); 

I tried a lot of everything and nothing worked, so finally I decided to manually do this by deleting the session record from the database myself.

Here is the code I used: app.get ('/ logout', function (req, res, next) {

  if ( req.isUnauthenticated() ) { // you are not even logged in, wtf res.redirect( '/' ); return; } var sessionCookie = req.cookies['connect.sid']; if ( ! sessionCookie ) { // nothing to do here res.redirect( '/' ); return; } var sessionId = sessionCookie.split( '.' )[0].replace( 's:', '' ); thinky.r.db( 'test' ).table( 'session' ).get( sessionId ).delete().run().then( function( result ) { if ( ! result.deleted ) { // we did not manage to find session for this user res.redirect( '/' ); return; } req.logout(); res.redirect( '/' ); return; }); }); 

So I hope this helps someone :)

+4
source

res.redirect('/') will complete the answer, you cannot subsequently call write (), end (), send (), json () ... etc.

Similar:

 app.post('/logout', function(req, res){ req.logOut(); res.redirect("/"); }); 

deserializeUser should return the user instead of id:

 passport.deserializeUser(function(id, done) { findUser(id, function(err, user) { if(err) { done(err) } else { done(null, user); } } }); 

I briefly discussed, I understand that the username / password digest is stored in the browser (and not on the server), so req.logout does not help, there is no way to clear it from the server. You just close the browser and open again, which means logging out.

You can use the variable in the cookie or session to mark the session as logging out, but I think we should not do this because the username / password is still in the browser.

This is a digest!

0
source

All Articles