在一个路由中创建的会话在其他路由中不可用

A session that is created in a route is not available in other routes

我正在尝试在我的 node.js 应用程序中设置会话。为此,我使用模块 "express"、"express-session" 和 "express-mysql-session" 将它们存储在我服务器上的数据库中。只要我只访问创建会话的路由内的 req.session 参数,我的代码就可以正常工作。在其他路由(甚至是启动文件)中,创建的参数会引发未定义的错误。

我已经尝试在启动文件中创建 app.use(session(...))。如果我这样做,一切正常,并且在某些路由中创建的参数也可用于其他路由。但是因为我想让启动文件尽可能小,所以这些代码行应该在一个路由中处理。

这是我的代码: login.js(一条路线)

var express = require('express');
var router = express.Router();
var session = require('express-session');
var MySQLStore = require('express-mysql-session');

var dbOptions = {
    host: "ip",
    user: "user",
    password: "pw",
    database: "some db"
};

var sessionStore = MySQLStore(dbOptions);

router.use(session({
    key: 'some key',
    secret: 'some secret',
    store: sessionStore,
    resave: false,
    saveUninitialized: false
}));

router.post('/login', (req, res) =>{
    req.session.username = req.body.username;
    res.end("done");
});

router.get('/sessionTest', (req, res) => {
    if(req.session.username) {
        res.write(`<h1>Hello ${req.session.username} </h1><br>`);
        res.end('<a href='+'/timetracking/logout'+'>Logout</a>');
    }
    else {
        res.write('<h1>Please login first.</h1>');
        res.end('<a href='+'/timetracking/login'+'>Login</a>');
    }
});

router.get('/logout',(req,res) => {
    req.session.destroy((err) => {
        if(err) {
            return console.log(err);
        }
        res.redirect('/timetracking/login');
    });

});

module.exports = router;

timetracking.js(启动文件)

var http = require('http');
const express = require('express');
const app = express();
var gets = require('./lib/gets');
var login = require('./lib/login');
const session = require('express-session');


//Make '/timetracking/' to the standard handler for get requests
app.use('/timetracking', [gets, login]);

app.get('/test', (req, res) =>{
    res.send(req.session.username);
});

app.listen(80);

当我加载时 localhost/test 我仍然可以在 Web 开发人员工具中看到 cookie。但是 "req.session.username" 是未定义的。

感谢您的帮助!

req.session 仅在会话中间件执行后出现的路由中可用(取决于顺序)。而且,如果会话中间件仅在一个路由器上,那么 req.session 将仅在匹配该路由器的路由中可用,并且仅在给定请求的路由器 运行 之后可用。

因此,如果您希望 req.session 在所有路由中有效,则需要尽早定义中间件,并且中间件 运行 在所有可能的路由(您想要使用它),不仅在某些路由器中仅在某些路径上 运行 。

请记住,是您的会话中间件对任何给定的传入请求设置 req.session。在您想要访问 req.session.

之前,它必须根据给定请求 运行

您不必将会话中间件直接放入启动文件中。你仍然可以把它放在它自己的模块中,你只需要从启动文件加载那个模块并将它传​​递给 app 对象,这样它就可以在你的任何路由之前初始化全局中间件。

这是一个示例启动文件:

const express = require('express');
const app = express();

// initialize global middleware
require('./myMiddleware')(app);

// set up other routers and routes here
// and start the server

还有一个 myMiddlware.js 文件:

// load and initialize session stuff
const session = ....;

module.exports = function(app) {
    // install session middleware
    app.use(session(...))
}