express-session设置req.session.user触发undefined报错如何解决?
报错原因与解决方案
TypeError: Cannot set property 'user' of undefined的本质是代码执行到赋值语句时,req.session的值为undefined,可按以下步骤排查修复:
1. 调整中间件与路由的注册顺序
必须保证所有路由的注册操作,全部放在session中间件注册之后。如果你的路由是拆分到外部文件通过require引入,也需要将引入路由的语句放在app.use(session(...))之后。如果顺序颠倒,请求进入路由时session还未挂载到req对象上,自然无法访问req.session。
正确的注册顺序示例:
// 先注册依赖中间件 var session = require("express-session"); var cookieParser = require('cookie-parser'); app.use(cookieParser()); app.use(session({ name: 'app.sid', secret: "1234567890QWERTY", resave: true, saveUninitialized: true })); // 再注册所有路由 app.post('/login', 登录路由处理逻辑) // 引入外部路由也必须放在session中间件之后 // const userRouter = require('./routes/user') // app.use('/user', userRouter)
2. 校验login函数的传参完整性
你在路由中调用login函数时,必须按(用户参数, req, res)的顺序传全三个参数,如果漏传req,会导致login函数内部的req变量为undefined,进而触发该报错。
路由调用的正确示例:
app.post('/login', (req, res) => { const loginUser = { lEmail: req.body.email, lPassword: req.body.password } // 三个参数必须完整传入 login(loginUser, req, res) })
3. 修正数据库查询的回调写法
如果你使用的是原生mysql/mysql2驱动,查询回调的第一个参数为错误对象,第二个参数才是查询结果,你当前的回调写法会把错误对象当做rows处理,虽然你反馈可正常拿到查询结果,但仍建议修正写法避免隐藏异常:
connection.query(query, user.lEmail, function (err, rows) { if (err) { console.log('数据库查询错误:', err) return res.status(500).send('服务器内部错误') } // 原有查询逻辑不变 if (rows && rows.length) { bcrypt.compare(user.lPassword, rows[0].password, function (result) { if (result) { req.session.user = rows[0] res.sendFile(path.join(__dirname + "/views/home.html")); } else { console.log("Incorrect password"); res.status(400).send('密码错误') } }); } else { console.log("Incorrect Email Address"); res.status(400).send('邮箱不存在') } });
注意:你之前尝试直接给引入的全局
session模块对象设置user属性是错误用法,express-session会为每个请求生成独立的会话对象,只能通过req.session访问当前请求对应的会话,直接修改全局session模块对象没有任何作用。
内容的提问来源于stack exchange,提问作者bob_jones
相关产品推荐
相关产品推荐

