Node.js JWT鉴权获取用户关联seances报id未定义错误
错误原因
接口返回id not defined是因为代码里直接使用了未声明的变量id:JWT鉴权中间件将解析后的认证用户ID挂载在req.id属性上,但控制器查询时没有从请求对象中读取该值,直接引用独立变量id触发引用错误。
另外现有代码还存在路由与控制器方法不匹配的问题:学生端课表路由/api/etudiant/seance绑定的是afficherSeancesEtudiant方法,但提供的控制器代码仅实现了教师端查询方法afficherSeancesEnseignant,直接访问学生端接口还会触发方法不存在的错误。
修复方案
1. 修正控制器取值逻辑
首先在控制器顶部导入依赖的模型,查询时通过req.id读取已认证用户的ID,同时统一异步写法、增加空值判断避免衍生错误,修正后的教师端课表查询代码如下:
// 控制器顶部导入所需模型,根据实际项目模型命名调整 const db = require("../models"); const Enseignant = db.enseignant; const Seance = db.seance; exports.afficherSeancesEnseignant = async (req, res) => { try { // 从req对象读取鉴权中间件挂载的用户ID,不要直接使用未定义的id变量 const enseignant = await Enseignant.findOne({ where: { userId: req.id } }); if (!enseignant) { return res.status(404).send({ message: "未查询到对应教师信息" }); } const matricule = enseignant.matricule; const seanceList = await Seance.findAll({ where: { enseignant: matricule } }); res.status(200).send(seanceList); } catch (e) { res.status(500).send({ message: e.message }); } }
2. 补全学生端课表查询方法
按照同样逻辑实现路由绑定的afficherSeancesEtudiant方法,匹配学生端接口请求:
const Etudiant = db.etudiant; exports.afficherSeancesEtudiant = async (req, res) => { try { // 同样通过req.id读取当前登录学生的用户ID const etudiant = await Etudiant.findOne({ where: { userId: req.id } }); if (!etudiant) { return res.status(404).send({ message: "未查询到对应学生信息" }); } // 根据实际业务中课表与学生的关联字段调整查询条件 const seanceList = await Seance.findAll({ where: { etudiant: etudiant.matricule } }); res.status(200).send(seanceList); } catch (e) { res.status(500).send({ message: e.message }); } }
3. 路由配置校验
如果需要开放教师端课表查询接口,在路由文件中补充对应路由配置,挂载对应权限校验中间件即可:
// 教师端课表查询路由示例 app.get( "/api/enseignant/seance", [ authJwt.verifyToken, authJwt.isEnseignant ], controller.afficherSeancesEnseignant );
验证说明
- 请求时确保
x-access-token请求头携带对应用户角色的有效JWT,过期、伪造的token会被鉴权中间件拦截 - 所有关联查询的字段名(比如
userId、matricule、enseignant、etudiant)需要和数据库模型定义保持一致,避免出现字段不存在的查询错误
内容的提问来源于stack exchange,提问作者Amar Mahdi
相关产品推荐
相关产品推荐

