登录路由设置session.userid时出现Cannot set properties of undefined报错
问题原因及解决方案
核心错误点
- session中间件变量名写错:你引入的是
const session = require('express-session'),但配置中间件时误用了sessions(多了一个s),导致中间件根本未生效,req.session自然为undefined。 - 响应发送后操作session:你先调用
res.json()发送了响应,之后才去设置req.session——此时响应已结束,session的修改无法被正确保存,逻辑顺序完全颠倒。 - 全局变量
sess的错误使用:全局变量会在多用户并发场景下互相覆盖,完全没必要,直接使用每个请求独立的req.session即可。 - 错误分支未终止执行:第一个
if(!user)分支中返回res.json()后未加return,会导致后续代码继续执行,可能引发额外逻辑错误。
修正后的代码
第一步:修正session中间件配置
const session = require('express-session') const oneDay = 1000 * 60 * 60 * 24; // 修正变量名:使用session而非sessions app.use(session({ secret: "thisismysecrctekeyfhrgfgrfrty84fwir767", saveUninitialized: true, cookie: { maxAge: oneDay }, resave: false }));
第二步:修正登录路由代码
router.post('/login', async(req, res)=>{ const { id, password } = req.body; try { // 校验用户ID const user = await User.findOne({id: id}) if(!user) { // 加return终止后续代码执行 return res.json({message: "Invalid ID#"}) } // 校验密码 if(await bcrypt.compare(password, user.pass)){ const token = jwt.sign({ id, }, "01021997", { expiresIn: "30d", }) console.log(token) // 先设置session,再发送响应 req.session.userid = user.id; // 可选:添加session保存回调,确保会话写入成功 req.session.save((err) => { if(err) { console.error(err); return res.status(500).json({auth: false, message: "Failed to save session"}) } res.json({auth: true, message: "logged in succesfully", token: token}) }) }else{ res.status(400) res.json({auth: false, message: "Invalid ID# or password!"}) } } catch (err) { console.error(err.message) res.status(500).json({auth: false, message: "Server error"}) } })
额外注意事项
- 绝对不要用全局变量存储用户会话,每个请求的
req.session是独立隔离的,专门用于存储当前用户的会话数据。 - 发送响应(
res.json()/res.send()等)之后的代码尽量避免执行,必要时用return终止函数,防止逻辑混乱。 - 开发环境可以用默认的内存存储session,但生产环境必须配置持久化存储引擎(比如
express-mysql-session),否则会导致内存泄漏和会话丢失。
内容的提问来源于stack exchange,提问作者Tarek Gharbi
相关产品推荐
相关产品推荐

