You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

添加角色权限控制时出现TypeError: Cannot read properties of undefined (reading 'role')错误排查求助

添加角色权限控制时出现TypeError: Cannot read properties of undefined (reading 'role')错误排查求助

嘿,我看你在给应用加角色权限控制的时候碰到了这个头疼的错误,咱们一步步拆解问题根源,把它搞定!

这个错误的核心原因很清晰:req.user是undefined,所以你没法读取它的role属性。咱们来看具体哪里出了问题以及怎么修复:

1. 问题根源:authenticateToken中间件没把用户信息挂载到req.user上

你的authenticateToken目前只做了一件事:验证token是否有效,但没有把解码后的用户信息或者数据库查询到的用户实例挂载到req对象的user属性上。后面的restrict中间件自然就拿不到req.user了。

看你当前的authenticateToken代码:

const authenticateToken = async (req, res, next) => {
  try {
    const token = req.cookies.jwt
    if(token){
      jwt.verify(token,process.env.JWT_SECRET,(err)=>{
        if(err){
          console.log(err.message)
          res.redirect("/login")
        }else{
          next()
        }
      })
    }else{
      res.redirect("/login")
    }
  } catch (error) {
    res.status(401).json({
      succeded: false,
      error: "Not authorized"
    })
  }
};

这里调用jwt.verify时其实能拿到decodedToken(里面包含你生成token时传入的userId),但你没利用它去查询用户并挂载到req.user上。

修复authenticateToken

把它改成这样,参考你checkUser中间件的逻辑,查询用户并挂载到req.user:

const authenticateToken = async (req, res, next) => {
  try {
    const token = req.cookies.jwt
    if(token){
      jwt.verify(token, process.env.JWT_SECRET, async (err, decodedToken) => {
        if(err){
          console.log(err.message)
          res.redirect("/login")
        }else{
          // 根据解码出的userId查询用户,挂载到req.user
          const user = await User.findById(decodedToken.userId);
          req.user = user;
          next()
        }
      })
    }else{
      res.redirect("/login")
    }
  } catch (error) {
    res.status(401).json({
      succeded: false,
      error: "Not authorized"
    })
  }
};

2. 修复restrict中间件的逻辑漏洞

你当前的restrict中间件里,不管权限校验是否通过,都会执行next(),这会导致即使用户权限不够,也会继续执行后面的控制器代码,这是个逻辑bug。另外最好先判断req.user是否存在,避免再次触发类似的undefined错误。

修改后的restrict:

const restrict = (role) =>{
  return(req,res,next)=>{
    // 先检查req.user是否存在,防止未认证的情况
    if(!req.user){
      const error = new CustomError("No auth", 401);
      return next(error);
    }
    if(req.user.role !== role){
      const error = new CustomError("No auth", 403)
      return next(error)
    }
    // 权限校验通过,继续执行
    next()
  }
}

注意这里用了return next(error),确保错误抛出后不会再执行后面的next()。

3. 额外检查:确认CustomError已正确导入

别忘了在authMiddleware.js顶部确认你已经导入了自定义的CustomError类,不然会触发新的错误。比如:

import CustomError from './path-to-your-custom-error-file.js';

做完这些修改后,再去访问/about页面,应该就能正常校验管理员权限,不会再出现那个TypeError了!

备注:内容来源于stack exchange,提问作者metkopetru

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.21 10:39:38