Javascript 没有 req.session.save() 会话不会保存在 Node.js 中

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26531143/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-22 23:00:09  来源:igfitidea点击:

Sessions won't save in Node.js without req.session.save()

javascriptnode.jssessionexpress

提问by PuppyKevin

I'm building a website using Node.js, Express, and Redis for session management. For whatever reason, if I have a session variable (isLoggedInin this example), and I refresh the page, the variable doesn't get saved, however, if I call req.session.save()after setting the variable, it does get saved to Redis (redis-cli monitor shows this - not calling save()shows that the variable isn't there, whereas calling save()shows it).

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

I'm using this to set up and start the server:

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

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

And then, in that route, I have:

然后,在这条路线上,我有:

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;

From that, I should be able to navigate to /login, have the session set isLoggedIn to true, and that should save automatically to Redis. After that, heading to /should tell me that I'm logged in. Loading /logindoes set the variable, the second log shows that, but loading /says that I'm not logged in. redis-cli monitor shows

从那以后,我应该能够导航到/login,将会话设置为 isLoggedIn 为 true,并且应该会自动保存到 Redis。之后,前往/应该告诉我我已登录。加载/login确实设置了变量,第二个日志显示了这一点,但加载/表示我没有登录。redis-cli 监视器显示

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

upon saving, which doesn't include the isLoggedInvariable, but adding in req.session.save()shows:

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

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

Any idea on why I have to call req.session.save()when all of the examples I've seen don't use it?

req.session.save()当我看到的所有例子都没有使用它时,为什么我必须打电话?

回答by PuppyKevin

Okay, so, I've figured it out. I'll put the answer here for anyone else that happens to get caught on this.

好的,所以,我已经想通了。我会将答案放在这里,供其他碰巧被此问题困扰的人使用。

For GET requests, the server assumes that you're going to be sending data back, and will automatically save session data once the route is fully processed.

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

For POST requests (what I'm using), however, the same assumption isn't made. Session states are only saved in one of two conditions - either when data is being sent out (through res.send, res.redirect, etc.), or if you manually call req.session.save(). I was already calling /login from an AJAX request, I just wasn't returning anything if certain conditions were met. Having the server respond to the client with some data after setting the session variable fixed this.

但是,对于 POST 请求(我正在使用的请求),没有做出相同的假设。会话状态仅保存在两个条件之一-要么当被发送出去的数据(通过res.sendres.redirect等等),或者如果你手动调用req.session.save()。我已经从 AJAX 请求中调用 /login,如果满足某些条件,我不会返回任何内容。在设置会话变量后让服务器用一些数据响应客户端解决了这个问题。