如何修复登录时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()就会触发错误。
同时存在几个冗余/不规范问题,可一并处理:
修复步骤
- 调整中间件顺序:将
app.use(session(sess))移至app.use(routes)之前,确保session中间件先于路由执行,这样路由处理时req.session已被初始化。 - 移除冗余的body-parser配置:Express内置了body解析功能,
app.use(express.json())和app.use(express.urlencoded({ extended: true }))已覆盖需求,adminLoginRoutes.js中bodyparser相关代码可删除。 - 修正拼写错误:
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
相关产品推荐
相关产品推荐

