没有 req.session.save() 会话不会保存在 Node.js 中 [英] Sessions won't save in Node.js without req.session.save()

查看:25
本文介绍了没有 req.session.save() 会话不会保存在 Node.js 中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm building a website using Node.js, Express, and Redis for session management. For whatever reason, if I have a session variable (isLoggedIn in 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).

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

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;

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

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 /login does set the variable, the second log shows that, but loading / says that I'm not logged in. redis-cli monitor shows

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

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

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

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

当我看到的所有示例都没有使用它时,为什么我必须调用 req.session.save() 有什么想法吗?

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

推荐答案

好的,我想通了.我会把答案放在这里,让其他碰巧遇到这个问题的人都知道.

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

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

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.

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

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.

这篇关于没有 req.session.save() 会话不会保存在 Node.js 中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆