Note that there are some explanatory texts on larger screens.

plurals
  1. PONode.js Express Passport Cookie Expiration
    primarykey
    data
    text
    <p>I am using Passport for authentication in my app, and I am also using Express. To summarize my issue: <strong>my login functionality works fine initially, but after <em>any</em> user's session times out, <em>no</em> users are able to log in.</strong></p> <p>I am using the standard Local strategy for authentication.</p> <p>I'll include as bare an example as possible based on my setup:</p> <pre><code>//------------- //Set up authentication with Passport //------------- var userModel = require('./models/user')(db); passport.use(new LocalStrategy( function(username, password, done) { var errorMessage = 'Incorrect username/password combination.'; userModel.GetUserByUsername(username, function(err, user) { if (err) { return done(err); } if (!user) { return done(null, false, { message: errorMessage }); } user.validatePassword(password, function(isPasswordCorrect) { if (!isPasswordCorrect) { return done(null, false, { message: errorMessage }); } //Update with login date userModel.UpdateUserWithLogin(username, user.currentLoginTime, function(err){ //if we have an error here, we should probably just log it if(err) { console.log(err); } }); return done(null, user); }); }); } )); passport.serializeUser(function(user, done) { done(null, user); }); passport.deserializeUser(function(user, done) { userModel.GetUserByUsername(user._id, function(err, user) { done(err, user); }); }); //------------- //Set up express and configure //------------- var sessionStore = new SkinStore(db); var app = express(); app.configure(function(){ app.set('port', process.env.PORT || 3000); app.set('views', __dirname + '/views'); app.engine('html', consolidate.swig); app.set('view engine', 'html'); swig.init({ root: '.', allowErrors: true, // allows errors to be thrown and caught by express instead of suppressed autoescape: false}); app.use(express.logger('dev')); app.use(express.bodyParser()); app.use(express.methodOverride()); app.use(express.cookieParser("[mysecrethere]")); app.use(express.session({ store: sessionStore, cookie: { expires : new Date(Date.now() + 3600000) } //1 Hour })); app.use(passport.initialize()); app.use(passport.session()); app.use(flash()); app.use(expressValidator); app.use(express.static(path.join(__dirname, 'public'))); //Dynamic helpers app.use(require('./helpers/DynamicHelpers')); app.use(app.router); }); app.get('/login', routes.login); app.post('/login', passport.authenticate('local', {failureRedirect: '/login', badRequestMessage: "Please enter username and password", failureFlash: true }), function(req, res) { var targetUrl = req.session.pageAfterLogin; delete req.session.pageAfterLogin; res.redirect(targetUrl || '/account'); }); app.get('/account', IsAuthenticated, routes.account.show); </code></pre> <p>And the IsAuthenticated helper function:</p> <pre><code>function IsAuthenticated(req,res,next){ if(req.isAuthenticated()) { next(); } else { //save the requested page and then redirected req.session.pageAfterLogin = req.url; req.flash("error", "You must be logged in first!"); res.redirect('/login'); } } </code></pre> <p>What I can find by debugging is that, after successful authentication (and after a cookie has expired), I hit this logic (from above):</p> <pre><code>function(req, res) { var targetUrl = req.session.pageAfterLogin; delete req.session.pageAfterLogin; res.redirect(targetUrl || '/account'); } </code></pre> <p>Where I can see that the "req" has the session properly set, with Passport information stored properly. Then, the redirect happens, the <strong>new</strong> request has no session information stored, and has an entirely new Session ID. I suspected that no cookie was being set on the client, and that does appear to be the case, which should explain the lack of consistent sessions.</p> <p>However, I cannot figure out <strong>why</strong> no new cookie is being set. Is there something wrong with how the app is configured that would indicate why this is happening?</p> <p>I should add that restarting the Node.js instance fixes the issue, it's just not something that would be tolerable in production.</p> <p>Thanks.</p> <p><strong>UPDATE</strong>: I ran Fiddler to see what was happening with HTTP/S traffic, and I can see that when it works initially, I'm getting a cookie set in the browser (I tried several) which is then passed back to the server on subsequent requests.</p> <p>When it <strong>doesn't</strong> work, the browser is not passing cookies to the server, and so Node is sending a Set-Cookie header that provides a new cookie each time. So far I've had no luck determining the cause of this.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload