You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复登录时req.session.save()报Cannot read property 'save' of undefined错误

问题:登录时调用req.session.save()出现TypeError: Cannot read property 'save' of undefined错误

在使用express-session保存登录session时触发上述错误,相关代码如下,请排查问题并给出修复方案。


adminLoginRoutes.js

const router = require('express').Router()
const {check, validationResult} = require('express-validator')
const path = require('path')
const bodyparser = require('body-parser')
const urlencodedParses = bodyparser.urlencoded({ extended: false })
const { AdminAccount } = require('../models')
const sequelize = require('sequelize')

router.use(bodyparser.json())
router.use(bodyparser.urlencoded({ extended: false }))


router.post('/', [
    check('email')
    .isEmail(),
    
    check('password')
    .isLength({ min: 6 })
    
], (req, res) => {
    const errors = validationResult(req)
    
    if(!errors.isEmpty()) {
        // res.send(errors)
    }
 
    AdminAccount.findOne({
        where: 
        {
            email: req.body.email
        }
    }).then(dbAdminLoginData => {

        if(!dbAdminLoginData) {
                res.json({ message: 'No user with that email address'});
                return;
            }
            
                const validPassword = dbAdminLoginData.checkPassword(req.body.password) 
                
                
                if (!validPassword) {
                    res.json({ message: 'Incorrect password!'});
                    return; 
                }

            req.session.save(() => {
                req.session.user_id = dbAdminLoginData.id
                req.session.username = dbAdminLoginData.email
                req.session.loggedIn = true;
    
                res.json({user: dbAdminLoginData, message: 'you are now logged in'})
            })
    }).catch(err => console.log(err))
})

server.js

const express = require('express')
const sequelize = require('./config/connection')
const exphbs = require('express-handlebars')
const hbs = exphbs.create({})
const session = require('express-session')

const SequalizeStore = require('connect-session-sequelize')(session.Store)

const sess = {
    secret: "Hello123!",
    cookie: {},
    resave: false,
    saveUninitialized: true,
    store: new SequalizeStore({
        db: sequelize
    })
}

const routes = require('./controllers')
// const routes = require('./routes/apiRoutes')
const app = express()
const PORT = process.env.PORT || 3001;

app.use(express.static('public'));
app.use(express.json());
app.use(routes)
app.use(express.urlencoded({ extended: true }));
app.use(session(sess))

app.engine('handlebars', hbs.engine)
app.set('view engine', 'handlebars')

sequelize.sync({ force: false }).then(() => {
    app.listen(PORT, () => console.log('now listening'))
})

问题原因与修复方案

核心问题:中间件加载顺序错误

Express中间件按加载顺序执行,你将app.use(routes)放在了app.use(session(sess))之前,导致路由处理请求时,session中间件尚未初始化,req.session自然为undefined,调用save()就会触发错误。

同时存在几个冗余/不规范问题,可一并处理:

修复步骤

  1. 调整中间件顺序:将app.use(session(sess))移至app.use(routes)之前,确保session中间件先于路由执行,这样路由处理时req.session已被初始化。
  2. 移除冗余的body-parser配置:Express内置了body解析功能,app.use(express.json())和app.use(express.urlencoded({ extended: true }))已覆盖需求,adminLoginRoutes.js中bodyparser相关代码可删除。
  3. 修正拼写错误:SequalizeStore应为SequelizeStore(注意字母q的位置),避免潜在运行问题。

修复后的server.js关键片段

// ... 其他代码保持不变 ...

app.use(express.static('public'));
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// 先初始化session中间件
app.use(session(sess))
// 再加载路由
app.use(routes)

// ... 其他代码保持不变 ...

修复后的adminLoginRoutes.js

const router = require('express').Router()
const {check, validationResult} = require('express-validator')
const { AdminAccount } = require('../models')

router.post('/', [
    check('email').isEmail(),
    check('password').isLength({ min: 6 })
], (req, res) => {
    const errors = validationResult(req)
    
    if(!errors.isEmpty()) {
        return res.status(400).json({ errors: errors.array() });
    }
 
    AdminAccount.findOne({
        where: { email: req.body.email }
    }).then(dbAdminLoginData => {
        if(!dbAdminLoginData) {
            return res.json({ message: '没有该邮箱对应的用户'});
        }
            
        const validPassword = dbAdminLoginData.checkPassword(req.body.password) 
        
        if (!validPassword) {
            return res.json({ message: '密码错误!'});
        }

        req.session.save(() => {
            req.session.user_id = dbAdminLoginData.id
            req.session.username = dbAdminLoginData.email
            req.session.loggedIn = true;

            res.json({user: dbAdminLoginData, message: '登录成功'})
        })
    }).catch(err => {
        console.log(err)
        res.status(500).json({ message: '服务器内部错误' })
    })
})

module.exports = router;

额外建议

  • 错误处理时返回对应HTTP状态码(如参数错误返回400,服务器错误返回500),方便前端精准处理。
  • 若不需要保存未初始化的session,可将sess中的saveUninitialized设为false,更符合隐私规范。

内容的提问来源于stack exchange,提问作者Ben

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 14:24:19