7

The session of my nodejs app is expiring every time I refresh the page, after login. It does work fine if I visit different pages but as soon as I refresh the page, the session ends. I've tried a couple of things but none of it seems to work. How can I keep it from expiring even after the page refresh? If I can store session in the database or someplace else to keep it from expiring.

Here are the files

Passport-init.js

 var mongoose = require('mongoose');
 var User = mongoose.model('user');
 var localStrategy = require('passport-local').Strategy;
 var bcrypt = require('bcrypt-nodejs');

module.exports = function(passport) {

passport.serializeUser(function(user, done) {
    console.log('serializing user:',user.username);
    done(null, user._id);
});

passport.deserializeUser(function(id, done) {

    User.findById(id, function(err, user) {

        if(err) {
            done(500,err);
        }
        console.log('deserializing user:',user.username);
        done(err, user);
    });
});

passport.use('login', new localStrategy({
    passReqToCallback : true
},
    function(req, username, password, done) {

        User.findOne({'username': username},

            function(err, user) {

                if(err) {
                    return done(err);
                }            
                if(!user) {
                    console.log("UserName or Password Incorrect");
                    return done(null, false);
                }
                if(!isValidPassword(user, password)) {
                    console.log("UserName or Password is Incorrect");
                    return done(null, false);
                }

                return done(null, user);
            });
    }));


passport.use('signup', new localStrategy({
    passReqToCallback : true

}, function(req, username, password, done) {

        User.findOne({'username': username},

            function(err, user) {

                if(err) {
                    console.log("Error in signup");
                    return done(err);
                }
                if(user) {
                    console.log("Username already exist" + username);
                    return(null, false);
                }
                else {

                    var newUser = new User();

                    newUser.username = username;
                    newUser.password = createHash(password);

                    newUser.save(function(err) {
                        if(err) {
                            console.log("Error in saving user");
                            throw err;
                        }
                        console.log(newUser.username + ' Registration succesful');    
                        return done(null, newUser);
                    });
                }

            });
}));


var isValidPassword = function(user, password) {
    return bcrypt.compareSync(password, user.password);
}

var createHash = function(password) {
    return bcrypt.hashSync(password, bcrypt.genSaltSync(10), null);
}
};

Auth.js

var express = require('express');
var router = express.Router();

module.exports = function(passport) {

router.get('/success', function(req, res) {

    res.send({state: 'success', user: req.user ? req.user : null});
});

router.get('/failure', function(req, res) {

    res.send({state: 'failure', user: null, message: 'Invalid Username or Password'});
});

router.post('/login', passport.authenticate('login', {

    successRedirect: '/auth/success',
    failureRedirect: '/auth/failure'
}));

router.post('/signup', passport.authenticate('signup', {

    successRedirect: '/auth/success',
    failureRedirect: '/auth/failure'
}));

router.get('/logout', function(req, res) {

    req.logout();
    res.redirect('/');
});

return router;

};

Server.js

var express = require('express');
var path = require('path');
var app = express();
var server = require('http').Server(app);
var logger = require('morgan');
var passport = require('passport');
var bodyParser = require('body-parser');
var cookieParser = require('cookie-parser');
var session = require('express-session');
var mongoose = require('mongoose');
var MongoStore = require('connect-mongo')(session);

 mongoose.connect("mongodb://localhost:27017/scriptknackData");
 require('./models/model');

 var api = require('./routes/api');
 var auth = require('./routes/auth')(passport);

app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(passport.initialize());
app.use(passport.session());

app.use(session({
secret: 'super secret key',
resave: true,
cookie: { maxAge: 60000 },
saveUninitialized: true,
store: new MongoStore({ mongooseConnection: mongoose.connection })
}));

var initpassport = require('./passport-init');
initpassport(passport);

app.use('/api', api);
app.use('/auth', auth);

 // catch 404 and forward to error handler
 app.use(function(req, res, next) {
 var err = new Error('Not Found');
 err.status = 404;
 next(err);
});


var port = process.env.PORT || 3000;
server.listen(port, function() {

console.log("connected");
});
aswheels media
  • 71
  • 1
  • 1
  • 3

4 Answers4

1

As per express-session documentation

cookie.maxAge Specifies the number (in milliseconds) to use when calculating the Expires Set-Cookie attribute. This is done by taking the current server time and adding maxAge milliseconds to the value to calculate an Expires datetime. By default, no maximum age is set.

And use express.session() before passport.session() to ensure login session is stored in correct order. passport docs

In your case you have specified maxAge as 60000ms (60sec) only. Try this:

...
app.use(session({
secret: 'super secret key',
resave: true,
cookie: { maxAge: 8*60*60*1000 },  // 8 hours
saveUninitialized: true,
store: new MongoStore({ mongooseConnection: mongoose.connection })
}));

app.use(passport.initialize());
app.use(passport.session());
...

Increase your cookie maxAge value according to your need, it will solve your issue.

Dennis
  • 102
  • 2
  • 8
shezy
  • 11
  • 2
  • 2
    It does not. No matter what value I give to maxAge, the session is expiring as soon as I am refreshing the page – aswheels media Aug 28 '17 at 17:08
  • @aswheelsmedia did you ever find a solution to this? I'm still facing the same issue even with the cookie.maxAge setting for 8 hours :( – Matthew Wolman Jun 24 '20 at 19:52
0

I was facing the same issue as you and I got the problem fixed by doing this:

If anyone is having issues, this could probably help to solve it.

app.use(session({
    secret: "our-passport-local-strategy-app",
    resave: true,
    saveUninitialized: true,
    cookie: {
        maxAge: 24 * 60 * 60 * 1000
    },
    store: new MongoStore({
        mongooseConnection: mongoose.connection,
        ttl: 24 * 60 * 60 // Keeps session open for 1 day
    })
}));
JulianSoto
  • 182
  • 1
  • 4
  • 15
0

I had this problem and I found out how to fix it. In my case, this problem was just during using localhost during running react app on own port. I use the build production version, there was no problem. But it is not good to run build every time you need to see changes.

First I run Nodejs on 5000 port at localhost.

In React's package.json, I added "proxy": "http://localhost:5000/". After that, I ran react app on port 3000. Now when I use fetch, the URL to my API is not http://localhost:5000/api/login but just /api/login.

You can read more about that here: https://create-react-app.dev/docs/proxying-api-requests-in-development/

Do not forget to remove the proxy from package.json when you will deploy to the server. This is good only for the development version.

Matej Peluha
  • 163
  • 9
-2

As per the fine manual (emphasis mine):

Note that enabling session support is entirely optional, though it is recommended for most applications. If enabled, be sure to use express.session() before passport.session() to ensure that the login session is restored in the correct order.

In your case, the order is not correct. Try this:

...
app.use(session({
secret: 'super secret key',
resave: true,
cookie: { maxAge: 60000 },
saveUninitialized: true,
store: new MongoStore({ mongooseConnection: mongoose.connection })
}));

app.use(passport.initialize());
app.use(passport.session());
...
robertklep
  • 198,204
  • 35
  • 394
  • 381