【问题标题】:NodeJS express session expire after page refresh页面刷新后NodeJS express会话过期
【发布时间】:2018-02-04 05:05:02
【问题描述】:

登录后,每次刷新页面时,我的 nodejs 应用程序的会话都会过期。如果我访问不同的页面,它确实可以正常工作,但是一旦我刷新页面,会话就会结束。我已经尝试了几件事,但似乎都没有奏效。即使在页面刷新后如何防止它过期?如果我可以将会话存储在数据库或其他地方以防止它过期。

这是文件

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");
});

【问题讨论】:

  • 找到解决方案了吗?
  • 嘿兄弟,你能找到解决办法吗?
  • 我也有同样的问题,但这只会发生在本地主机上。当我将其上传到实时服务器会话时,会按预期工作。

标签: node.js express express-session


【解决方案1】:

根据快速会话documentation

cookie.maxAge 指定计算 Expires Set-Cookie 属性时要使用的数字(以毫秒为单位)。这是通过获取当前服务器时间并将 maxAge 毫秒添加到该值来计算 Expires 日期时间来完成的。默认情况下,没有设置最大年龄。

并在 passport.session() 之前使用 express.session() 以确保登录会话以正确的顺序存储。 passport docs

在您的情况下,您仅将 maxAge 指定为 60000ms (60sec)。试试这个:

...
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());
...

根据您的需要增加您的cookie maxAge 值,它将解决您的问题。

【讨论】:

  • 它没有。无论我为 maxAge 赋予什么值,只要我刷新页面,会话就会过期
  • @aswheelsmedia 你有没有找到解决方案?即使将 cookie.maxAge 设置为 8 小时,我仍然面临同样的问题 :(
【解决方案2】:

我遇到了和你一样的问题,我通过这样做解决了问题:

如果有人遇到问题,这可能有助于解决问题。

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
    })
}));

【讨论】:

    【解决方案3】:

    我遇到了这个问题,我找到了解决方法。就我而言,这个问题只是在使用 localhost 在自己的端口上运行反应应用程序期间。我使用的是构建生产版本,没有问题。但是每次需要查看更改时都运行 build 并不好。

    首先我在 localhost 的 5000 端口上运行 Nodejs。

    在 React 的 package.json 中,我添加了“proxy”:“http://localhost:5000/”。之后,我在端口 3000 上运行 react app。现在,当我使用 fetch 时,我的 API 的 URL 不是 http://localhost:5000/api/login 而只是 /api/login。

    您可以在此处阅读更多相关信息: https://create-react-app.dev/docs/proxying-api-requests-in-development/

    当您将部署到服务器时,不要忘记从 package.json 中删除代理。这仅适用于开发版本。

    【讨论】:

      【解决方案4】:

      根据the fine manual(强调我的):

      请注意,启用会话支持是完全可选的,但建议大多数应用程序使用它。 如果启用,请务必在passport.session() 之前使用express.session(),以确保以正确的顺序恢复登录会话。

      在您的情况下,顺序不正确。试试这个:

      ...
      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());
      ...
      

      【讨论】:

        猜你喜欢
        • 2013-12-22
        • 2011-07-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-07-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多