Express-Session在生产环境中无法持久化。

5

我正在尝试在gcloud生产环境中运行我的nodejs应用程序,但是express-session没有按预期工作。 在我的本地开发中它运行得很好。

app.js

var express = require('express');

var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var session = require('express-session');

// var http = require('http');
// var reload = require('reload');


var index = require('./routes/index');
var users = require('./routes/users');
var user = require('./routes/user');
var dashboard = require('./routes/dashboard');
var search = require('./routes/search');
var profile = require('./routes/profile');
var ajax = require('./routes/admin-ajax');
var logout = require('./routes/logout');
var administrator = require('./routes/administrator');



var app = express();




app.set('port', process.env.PORT || 3000);

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');

app.use(cookieParser('mysessionsecretkey'));


// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, 'public')));


app.set('trust proxy', 1) // trust first proxy
app.use(session({
  secret: 'mysessionsecretkey',
  resave: false,
  saveUninitialized: true,
  cookie:{
    secure:true,
    maxAge: 864000000 
  }
}))


app.use('/js', express.static(__dirname + '/node_modules/bootstrap/dist/js')); // redirect bootstrap JS
app.use('/js', express.static(__dirname + '/node_modules/jquery/dist')); // redirect JS jQuery
app.use('/js', express.static(__dirname + '/node_modules/jquery-ui-dist')); // redirect JS jQuery
app.use('/js', express.static(__dirname + '/node_modules/popper.js/dist/umd')); 
app.use('/js', express.static(__dirname + '/node_modules/moment/min')); 
app.use('/js', express.static(__dirname + '/node_modules/lodash')); 
app.use('/css', express.static(__dirname + '/node_modules/jquery-ui-dist')); // redirect JS jQuery
app.use('/css', express.static(__dirname + '/node_modules/bootstrap/dist/css')); // redirect CSS bootstrap
app.use('/css', express.static(__dirname + '/node_modules/font-awesome/css')); 
app.use('/css', express.static(__dirname + '/node_modules/animate.css')); 
app.use('/js', express.static(__dirname + '/node_modules/datatables.net/js')); 
app.use('/js', express.static(__dirname + '/node_modules/datatables.net-bs4/js')); 
app.use('/css', express.static(__dirname + '/node_modules/datatables.net-bs4/css')); 




app.use('/', index);
app.use('/users', users);
app.use('/user', user);
app.use('/dashboard', dashboard);
app.use('/search', search);
app.use('/profile', profile);
app.use('/admin-ajax', ajax);
app.use('/logout', logout);
app.use('/administrator', administrator);



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


// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});


// var server = http.createServer(app)

// //reload(app);
// server.listen(app.get('port'), function () {
//  console.log('Web server listening on port ' + app.get('port'))
// });





module.exports = app;

中间件 - 检查用户是否已登录。
middleware.isUserLoggedIn = function(){
    return function(req, res, next){
        if(!_.isEmpty(req.session) && !_.isEmpty(req.session.user)){
            return next();
        }        
        return res.send('Session Expired'); //only for testing purpose
        return res.redirect('/');//original code
    }
}

package.json

{
  "name": "onlineexam",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "start": "node ./bin/www"
  },
  "main": "app.js",
  "dependencies": {
    "animate.css": "^3.5.2",
    "bcrypt": "^1.0.3",
    "body-parser": "~1.18.2",
    "bootstrap": "^4.0.0-beta.2",
    "cookie-parser": "~1.4.3",
    "datatables.net": "^1.10.16",
    "datatables.net-bs4": "^1.10.16",
    "debug": "~2.6.9",
    "express": "~4.15.5",
    "express-session": "^1.15.6",
    "font-awesome": "^4.7.0",
    "glob": "^7.1.2",
    "jquery": "^3.2.1",
    "jquery-ui-dist": "^1.12.1",
    "jsonwebtoken": "^8.1.0",
    "lodash": "^4.17.4",
    "moment": "^2.19.4",
    "mongodb": "^2.2.33",
    "morgan": "~1.9.0",
    "node-fetch": "^1.7.3",
    "popper.js": "^1.12.9",
    "pug": "2.0.0-beta11",
    "serve-favicon": "~2.4.5"
  },
  "devDependencies": {
    "browser-sync": "^2.18.13",
    "concat-files": "^0.1.1",
    "connect-browser-sync": "^2.1.0",
    "nodemon": "^1.12.5",
    "reload": "^2.2.2"
  }
}

测试网站

URL:https://node-matrimony-191001.appspot.com/

电话:9999999999

express-session 应该将登录用户信息存储并在每个路由中提供信息。


你可以设置环境变量:DEBUG=express-session,如果有的话,查看错误消息吗? - Abhyudit Jain
在gcloud中?我对类似gcloud的环境非常陌生,不知道它是如何工作的? - Alaksandar Jesus Gene
1个回答

5

express-session使用

MemoryStorage

MemoryStorage是专门为调试和开发而设计的,不适用于生产环境。在大多数情况下,它会泄漏内存,无法扩展到单个进程之外。

在生产环境中,您可以使用其他存储方式,并且您可以找到许多与express-session兼容的存储方式。

以下链接包含兼容的会话存储:

https://github.com/expressjs/session#compatible-session-stores

请始终记住,会话存储在服务器端。


4
谢谢。由于这个问题,我放弃了那个项目,并开始使用Angular和JWT继续前进...问题是如果express-session不适用于生产环境,为什么它如此流行...这让我付出了两个月的努力,现在我只能重新开始。 - Alaksandar Jesus Gene
@AlaksandarJesusGene - 我认为 express-session 只是在服务器端为您创建会话,但数据存储的位置才是关键。他们建议不要将数据存储在服务器内存中。我们可以使用任何安全的存储,如 MongoDB 等。 - 151291

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接