Сессии не будут сохраняться в Node.js без req.session.save()
Я создаю веб-сайт с использованием Node.js, Express и Redis для управления сеансами. По какой-либо причине, если у меня есть переменная сеанса (isLoggedIn
в этом примере), и я 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. После этого, заголовок /
должен сказать мне, что я вошел в систему. Loading /login
задает переменную, второй журнал показывает это, но загружает /
говорит, что я не вошел в систему. Redis-cli monitor показывает
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
Итак, я понял это. Я отвечу здесь всем, кто попадает на это.
Для запросов GET сервер предполагает, что вы собираетесь отправлять данные, и автоматически сохраняет данные сеанса после того, как маршрут будет полностью обработан.
Однако для запросов POST (то, что я использую) такое же предположение не выполняется. Состояние сеанса сохраняется только в одном из двух условий - либо при отправке данных (через res.send
, res.redirect
и т.д.), req.session.save()
вызове вручную req.session.save()
. Я уже звонил/выходил из запроса AJAX, я просто ничего не возвращал, если были выполнены определенные условия. После того, как сервер ответит клиенту с некоторыми данными после установки переменной сеанса, это исправлено.