express-session 和 connect-mongo 的会话未持续
Sessions not persisting with express-session and connect-mongo
我的 express 服务器正在使用 express-session 和 connect-mongo,它会为同一用户的每个请求生成一个新的 session,而不是像预期的那样保留一个 session到。这是我第一次使用 express sessions 但我认为这不是我的代码的问题。测试时我是唯一的用户,当我查看我的 MongoDB 时,有一堆新的 session。每次我向需要使用 session 变量的路由发出请求时,它都会生成另一个新的 session.
编辑:session id 没有被客户端存储,因此每个请求都会产生一个新的 session。正在发送正确的 set-cookie header,所以我不确定为什么它不起作用。我使用 Firefox 作为我的客户端。
编辑 2:尝试使用 Edge 和 Chrome,他们也没有设置 session cookie。我是 sessions 的新手,所以我不知道为什么它不能正常工作。
// 3rd party modules
const util = require('util');
const express = require('express');
const bodyParser = require('body-parser');
const multer = require('multer');
const morgan = require('morgan');
const mongoose = require('mongoose');
const config = require('config');
const session = require('express-session');
const MongoStore = require('connect-mongo')(session);
// Custom classes
const AuthService = require('./services/authService');
// Models
const Account = require('./models/account');
// Load .env config file
const envConfigResult = require('dotenv').config();
if (envConfigResult.error) {
throw envConfigResult.error;
}
// Instances
let auth;
let upload = multer();
const app = express();
// Parse request data and store in req.body
app.use(bodyParser.json()); // json
app.use(bodyParser.urlencoded({ extended: true })); // x-www-form-url-encoded
app.use(upload.array()); // multipart/form-data
// Setup logging
app.use(morgan('dev'));
// JWT error handling
app.use(function (err, req, res, next) {
// TODO: Implement proper error code
res.status(401).send(err);
if (err.name === 'UnauthorizedError') {
res.status(401).send('invalid token...');
}
});
async function main() {
try {
const mongoDbUrl = process.env.DB_HOST;
// Use new url parser and unified topology to fix deprecation warning
const mongoConnection = mongoose.connect(mongoDbUrl, { useNewUrlParser: true, useUnifiedTopology: true }).then(async function() {
console.log(`Successfully connected to MongoDB database at ${mongoDbUrl}!`);
}).catch(function(error) {
console.log(`Error whilst connecting to MongoDB database at ${mongoDbUrl}! ${error}`);
});
mongoose.set('useCreateIndex', true); // Fixes deprecation warning
} catch (err) {
console.log(`Error whilst doing database setup! ${err}`);
}
try {
app.use(session({
store: new MongoStore({ mongooseConnection: mongoose.connection, ttl: 86400 }),
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false,
cookie: {
path: "/",
maxAge: 3600000, // 1 hour
httpOnly: false,
secure: false // TODO: Update this on production
}
}));
console.log("Sessions successfully initialized!");
} catch (err) {
console.log(`Error setting up a mongo session store! ${err}`);
}
try {
// TODO: Initialize email service
auth = new AuthService.AuthService();
// TODO: Attach email service to auth service
} catch (err) {
console.log(`Error whilst doing initial setup. ${err}`);
}
}
main();
// Routes
const rootRoute = require('./routes/root');
const tokensRoute = require('./routes/tokens');
const captchaRoute = require('./routes/captcha');
// Route middlewares
app.use('/v1/', rootRoute.router);
app.use('/v1/tokens', tokensRoute.router);
app.use('/v1/captcha', captchaRoute.router);
try {
rootRoute.setAuthService(auth);
tokensRoute.setAuthService(auth);
} catch (err) {
console.log(`Error attaching auth service to routes! ${err}`);
}
var server = app.listen(8088, function() {
let host = server.address().address;
let port = server.address().port;
if (host == "::") {
console.log("Server running at http://127.0.0.1:%d", port);
} else {
console.log("Server running at http://%s:%d", host, port);
}
});
如 doc (or npm page) 中所述,您似乎忘记了一行:
app.use(session({
secret: 'foo',
store: new MongoStore(options)
}));
事实证明,现代浏览器会忽略 set-cookie headers,除非您在请求中包含 credentials: 'include'
。因此,我将客户端切换为使用 fetch 而不是 XMLHttpRequest,并将 credentials: 'include'
添加到其选项中。 (如果你没有正确设置 CORS,凭证将被忽略,所以我也必须这样做。)现在它工作正常。
TLDR:在您的请求中包含 credentials: 'include'
并确保服务器配置了 CORS。
我的 express 服务器正在使用 express-session 和 connect-mongo,它会为同一用户的每个请求生成一个新的 session,而不是像预期的那样保留一个 session到。这是我第一次使用 express sessions 但我认为这不是我的代码的问题。测试时我是唯一的用户,当我查看我的 MongoDB 时,有一堆新的 session。每次我向需要使用 session 变量的路由发出请求时,它都会生成另一个新的 session.
编辑:session id 没有被客户端存储,因此每个请求都会产生一个新的 session。正在发送正确的 set-cookie header,所以我不确定为什么它不起作用。我使用 Firefox 作为我的客户端。
编辑 2:尝试使用 Edge 和 Chrome,他们也没有设置 session cookie。我是 sessions 的新手,所以我不知道为什么它不能正常工作。
// 3rd party modules
const util = require('util');
const express = require('express');
const bodyParser = require('body-parser');
const multer = require('multer');
const morgan = require('morgan');
const mongoose = require('mongoose');
const config = require('config');
const session = require('express-session');
const MongoStore = require('connect-mongo')(session);
// Custom classes
const AuthService = require('./services/authService');
// Models
const Account = require('./models/account');
// Load .env config file
const envConfigResult = require('dotenv').config();
if (envConfigResult.error) {
throw envConfigResult.error;
}
// Instances
let auth;
let upload = multer();
const app = express();
// Parse request data and store in req.body
app.use(bodyParser.json()); // json
app.use(bodyParser.urlencoded({ extended: true })); // x-www-form-url-encoded
app.use(upload.array()); // multipart/form-data
// Setup logging
app.use(morgan('dev'));
// JWT error handling
app.use(function (err, req, res, next) {
// TODO: Implement proper error code
res.status(401).send(err);
if (err.name === 'UnauthorizedError') {
res.status(401).send('invalid token...');
}
});
async function main() {
try {
const mongoDbUrl = process.env.DB_HOST;
// Use new url parser and unified topology to fix deprecation warning
const mongoConnection = mongoose.connect(mongoDbUrl, { useNewUrlParser: true, useUnifiedTopology: true }).then(async function() {
console.log(`Successfully connected to MongoDB database at ${mongoDbUrl}!`);
}).catch(function(error) {
console.log(`Error whilst connecting to MongoDB database at ${mongoDbUrl}! ${error}`);
});
mongoose.set('useCreateIndex', true); // Fixes deprecation warning
} catch (err) {
console.log(`Error whilst doing database setup! ${err}`);
}
try {
app.use(session({
store: new MongoStore({ mongooseConnection: mongoose.connection, ttl: 86400 }),
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false,
cookie: {
path: "/",
maxAge: 3600000, // 1 hour
httpOnly: false,
secure: false // TODO: Update this on production
}
}));
console.log("Sessions successfully initialized!");
} catch (err) {
console.log(`Error setting up a mongo session store! ${err}`);
}
try {
// TODO: Initialize email service
auth = new AuthService.AuthService();
// TODO: Attach email service to auth service
} catch (err) {
console.log(`Error whilst doing initial setup. ${err}`);
}
}
main();
// Routes
const rootRoute = require('./routes/root');
const tokensRoute = require('./routes/tokens');
const captchaRoute = require('./routes/captcha');
// Route middlewares
app.use('/v1/', rootRoute.router);
app.use('/v1/tokens', tokensRoute.router);
app.use('/v1/captcha', captchaRoute.router);
try {
rootRoute.setAuthService(auth);
tokensRoute.setAuthService(auth);
} catch (err) {
console.log(`Error attaching auth service to routes! ${err}`);
}
var server = app.listen(8088, function() {
let host = server.address().address;
let port = server.address().port;
if (host == "::") {
console.log("Server running at http://127.0.0.1:%d", port);
} else {
console.log("Server running at http://%s:%d", host, port);
}
});
如 doc (or npm page) 中所述,您似乎忘记了一行:
app.use(session({
secret: 'foo',
store: new MongoStore(options)
}));
事实证明,现代浏览器会忽略 set-cookie headers,除非您在请求中包含 credentials: 'include'
。因此,我将客户端切换为使用 fetch 而不是 XMLHttpRequest,并将 credentials: 'include'
添加到其选项中。 (如果你没有正确设置 CORS,凭证将被忽略,所以我也必须这样做。)现在它工作正常。
TLDR:在您的请求中包含 credentials: 'include'
并确保服务器配置了 CORS。