在没有req.session.save()的情况下,Sessions不会在Node.js中保存

时间:2014-10-23 15:02:51

标签: javascript node.js session express

我使用Node.js,Express和Redis构建网站进行会话管理。无论出于何种原因,如果我有会话变量(在此示例中为isLoggedIn),并且我刷新页面,则变量不会被保存,但是,如果我在设置之后调用req.session.save()变量,它确实被保存到Redis(redis-cli监视器显示了这一点 - 不是调用save()表示变量不在那里,而调用save()显示它。)

我使用它来设置和启动服务器:

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 swig = require('swig');
var session = require('express-session')
var RedisStore = require('connect-redis')(session);

var routes = require('./routes/index');
var users = require('./routes/users');

var app = express();

// Configure the favicon first. This avoids other middleware from processing the request if we know the request is for the favicon.
app.use(favicon(__dirname + '/public/images/favicon.ico'));

// All other requests will require everything else.

// Set up the view engine.
app.set('view engine', 'html');
app.set('views', path.join(__dirname, '/views'));
app.engine('html', swig.renderFile);

// Set up our logger.
app.use(logger('dev'));

// Set up JSON parsing.
app.use(bodyParser.json());

// Set up encoded URL parsing.
app.use(bodyParser.urlencoded());

// Set up the cookie parser.
app.use(cookieParser('thedogsleepsatnight'));

// Set up our session store. This will use Redis as our session management.
app.use(session({
    resave: true,
    saveUninitialized: true,
    secret: "thedogsleepsatnight",
    store: new RedisStore()
}));

app.use(require('stylus').middleware(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', routes);

然后,在那条路上,我有:

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

router.get('/', function(req, res) {
    console.log(req.session.isLoggedIn);
    if (req.session.isLoggedIn) {
        console.log("Logged in!");
    } else {
        console.log("Not logged in");
    }

    res.render('index');
});

router.post('/login', function(req, res) {
    console.log("Going to set isLoggedIn. Currently: " + req.session.isLoggedIn);
    req.session.isLoggedIn = true;
    console.log("Set isLoggedIn. Currently: " + req.session.isLoggedIn);
});

module.exports = router;

由此,我应该能够导航到/login,将会话集isLoggedIn设置为true,并且应该自动保存到Redis。在此之后,前往/应该告诉我我已登录。加载/login会设置变量,第二个日志会显示,但加载/表示我&# 39; m未登录.redis-cli监视器显示

1414076171.241836 "setex" "sess:FIDJ9qDbX_0u9pzlC6VZEW76zZcyiPME" "86400" "{\"cookie\":{\"originalMaxAge\":null,\"expires\":null,\"httpOnly\":true,\"path\":\"/\"}}"

保存时,不包含isLoggedIn变量,但添加req.session.save()则显示:

1414076475.601644 "setex" "sess:FIDJ9qDbX_0u9pzlC6VZEW76zZcyiPME" "86400" "{\"cookie\":{\"originalMaxAge\":null,\"expires\":null,\"httpOnly\":true,\"path\":\"/\"},\"isLoggedIn\":true}"

在我看过的所有例子都没有使用它的时候,为什么我必须致电req.session.save()

1 个答案:

答案 0 :(得分:72)

好的,我已经弄清楚了。我会把答案放在其他任何碰巧遇到这个问题的人身上。

对于GET请求,服务器假定您将要发回数据,并在路由完全处理后自动保存会话数据。

对于POST请求(我正在使用的),但是没有做出相同的假设。会话状态仅保存在以下两种情况之一 - 发送数据时(通过res.sendres.redirect等),或者手动呼叫req.session.save()。我已经从AJAX请求调用/登录了,如果满足某些条件,我就不会返回任何内容。在设置会话变量后,让服务器使用某些数据响应客户端。