上传文件时快速会话中的数据消失

Data in express session disappear when upload file

我正在开发一个网络服务器并尝试创建上传文件路径。但我只需要登录的人可以上传文件。所以我添加了中间件来检查会话数据是否可用。但是会话数据在此路由中始终未定义。

我尝试重新加载并重新生成会话,但它仍然未定义。我将库从 "multer" 更改为 "express-fileupload" 但它没有效果。可能是因为内容的类型是 multipart-form-data。我不确定。

会话中间件设置。

const sessionMidleware = session({
  secret: 'My secret key',
  resave: false,
  saveUninitialized: false,
})

app.use(sessionMidleware)

我为了调试插入的中间件

app.post(
  '/sendinvoice',
  (req, res, next) => {
    console.log(req.session)
    next()
  },
  uploadCustomerInvoice().fields([
    { name: 'file', maxCount: 1 },
    { name: 'course_id', maxCount: 1 },
  ]),
  customerInvoice,
)

这是我登录注册时在其他路由中设置session的功能

module.exports = (req, profile, courses) => {
  req.session.profile = profile
  req.session.courses = courses
  req.session.isSuper = false
  req.session.isAdmin = false
  req.session.save()
}

我希望 req.session.profile 的输出是存储用户数据的对象,但实际输出是未定义的。

会话在使用 multer 时被覆盖,cls 包也会发生这种情况。

尝试在调用 multer instance 时添加承诺,并在 resolve 时继续执行下一行。我认为这应该可以解决问题。

您需要 SET 一个路由中的会话密钥才能在另一个路由中使用它。例如登录。

  1. 您登录,会话设置。用于以后验证用户。
  2. 每个需要认证的路由都需要检查会话密钥是否存在。
  3. 如果存在,继续。否则,它不会。

所以在你的情况下,

app.post('/login', (req,res) =>{
    //here check if logged in
    if(login){
        // Set the session
        req.session.someKey = someDataToVerifyUser;
    }
})

app.post('/upload', (req,res,next)=>{
    if(req.session.someKey && someVerification(req.session.someKey)){
        next();
    }else{
        res.status(400).send('Not Authorized')
    }
}, ..multer..., (req,res)=> {...})

编辑:
您可以使用 passport-js 来无缝注册和登录。

编辑2: 我做了一个最小的例子,看看是否有帮助:

const express = require('express');
const app = express();
var router = express.Router()
const session = require('express-session');
var multer = require('multer')

var upload = multer({ dest: './uploads/' })

var sess = {
    secret: 'mySecret',
    cookie: { token: null },
    saveUninitialized: false,
    resave: true
};

app.use(session(sess));

app.get('/', async (req, res) => {
    console.log("Hit The GET /:")
    req.session.token = 'hello';
    console.log("Setting the session:"+req.session.token+"\n"); // Outputs 'hello'
    res.send(req.session.token);
});
app.get('/me', async (req, res) => {
    console.log("Hit The GET /me:")
    console.log(`Printing the Session: ${req.session.token}\n`);
    res.send(req.session.token);
});
app.post('/', (req, res, next) => {
        console.log("Hit The POST /me:")
        console.log(`THERE IT IS ${req.session.token}\n`);
        next()
    },
    upload.single('avatar'),
    function (req, res, next) {
        console.dir(req.file);
        res.json(req.file)
    })

app.listen(8888, () => {
    console.log('Server Running At: 8888');
})

这是控制台输出:

Server Running At: 8888
Hit The GET /:
Setting the session:hello

Hit The GET /me:
Printing the Session: hello

Hit The POST /me:
THERE IT IS hello

{ fieldname: 'avatar',
  originalname: '304.png',
  encoding: '7bit',
  mimetype: 'image/png',
  destination: './uploads/',
  filename: '340cae7033576062253339d04519ed8a',
  path: 'uploads/340cae7033576062253339d04519ed8a',
  size: 4093 }

我终于弄明白 session 消失了,因为我忘记在请求中发送 cookie。我正在使用 Fetch API。所以我将 credentials: 'include' 添加到 header 然后它起作用了。谢谢。