Todo应用会话授权异常:req.session.userId返回undefined求助
问题排查与解决方案
核心问题1:错误的Session属性访问
你在addTask控制器里尝试获取req.session.userId,但登录时实际存入Session的是完整用户对象req.session.user,所以userId并不在req.session根节点下,而是嵌套在req.session.user.id中。
修正addTask代码:
exports.addTask = (req, res) => { const {task} = req.body; // 从session.user中正确提取用户ID const userId = req.session.user.id; const stmt = db.prepare(`INSERT INTO todos (user_id, task) VALUES (?, ?)`); stmt.run(userId, task, (err) => { if(err) { console.error(err.message); res.status(500).send({error: 'Failed to add task.'}); } else { res.sendStatus(200); } }); stmt.finalize(); };
核心问题2:登录控制器的逻辑漏洞
登录代码中,当密码不匹配时未终止函数执行,会继续创建无效会话:
if(!passMatch) { res.status(401).json({error: 'Invalid password.'}); // 缺少return,后续代码仍会执行并设置session }
修正后:
if(!passMatch) { return res.status(401).json({error: 'Invalid password.'}); }
会话中间件与请求验证建议
- Session中间件加载顺序:确保
app.use(session(...))代码在所有路由定义之前执行,否则路由无法访问req.session对象。 - SQLiteStore验证:确认已安装
connect-sqlite3包,且正确导入初始化:const SQLiteStore = require('connect-sqlite3')(session); - Thunder Client请求检查:
- 查看登录请求的响应头,确认
Set-Cookie字段包含sid会话ID。 - 在
checkAuth中间件添加console.log(req.headers.cookie),验证后续请求是否正确携带Cookie。 - 确保请求的域名、路径与Cookie配置的
path: '/'一致,避免Cookie无法传递。
- 查看登录请求的响应头,确认
额外优化建议
- 生产环境建议将Cookie的
httpOnly设为true,防止XSS攻击窃取会话ID。 resave: true可改为false,减少不必要的会话存储写入操作。
内容的提问来源于stack exchange,提问作者Nežumi
相关产品推荐
相关产品推荐

