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

开发verifyTokenAdmin中间件遇TypeError:无法读取isAdmin属性

解决JWT鉴权中间件的TypeError: Cannot read properties of undefined (reading 'isAdmin')错误

问题原因

你遇到的错误核心是verifyAdmin中间件里的req.Users完全未定义——你的verifyToken中间件只从JWT里提取了用户ID并存到req.userId,但没有从数据库查询用户信息,也没有把用户对象挂载到请求对象上,自然无法读取isAdmin属性。

解决方案

有两种可行的修复思路,根据业务需求选择:


方案1:验证Token后查询数据库获取用户信息

这种方式更安全,即使用户的isAdmin权限在Token签发后被修改,也能实时生效。

  1. 修改verifyToken中间件:引入User模型,验证Token后查询用户并挂载到req.user上(需改为异步函数):
const jwt = require('jsonwebtoken');
const User = require('../models/User'); // 路径根据项目结构调整

const verifyToken = async (req, res, next) => {
    const { authorization } = req.headers;

    if (!authorization) {
        return res.status(401).json('无效的授权信息')
    };

    // 优化Token提取逻辑:拆分Bearer和Token部分
    const token = authorization.split(' ')[1];
    if (!token) {
        return res.status(401).json('无效的Token格式');
    }

    try {
        const secret = process.env.JWT_SECRET;
        const data = jwt.verify(token, secret);

        const user = await User.findByPk(data.id);
        if (!user) {
            return res.status(404).json('用户不存在');
        }

        req.user = user; // 将用户对象挂载到请求上
        return next();
    } catch (err) {
        return res.status(400).json('Token验证失败');
    }
};

const verifyAdmin = (req, res, next) => {
    // 直接访问req.user的isAdmin属性
    if (req.user.isAdmin) {
        next();
    } else {
        return res.status(403).json("你无权执行此操作!");
    }
}

module.exports = {
  verifyToken,
  verifyAdmin,
};
  1. 路由无需修改:中间件执行顺序保持verifyToken→verifyAdmin即可。

方案2:生成Token时将isAdmin写入Payload

这种方式无需查询数据库,性能更高,但用户权限修改后需重新签发Token才会生效。

  1. 生成Token时添加isAdmin字段(在用户创建或登录逻辑中):
// 示例:登录成功后生成Token
const token = jwt.sign(
    { id: user.id, isAdmin: user.isAdmin }, // 将isAdmin写入Payload
    process.env.JWT_SECRET,
    { expiresIn: '24h' }
);
  1. 修改中间件:直接从Token解析结果中提取isAdmin:
const jwt = require('jsonwebtoken');

const verifyToken = (req, res, next) => {
    const { authorization } = req.headers;

    if (!authorization) {
        return res.status(401).json('无效的授权信息')
    };

    const token = authorization.split(' ')[1];
    if (!token) {
        return res.status(401).json('无效的Token格式');
    }

    try {
        const secret = process.env.JWT_SECRET;
        const { id, isAdmin } = jwt.verify(token, secret);

        req.userId = id;
        req.isAdmin = isAdmin; // 将isAdmin挂载到请求上
        
        return next();
    } catch (err) {
        return res.status(400).json('Token验证失败');
    }
};

const verifyAdmin = (req, res, next) => {
    if (req.isAdmin) {
        next();
    } else {
        return res.status(403).json("你无权执行此操作!");
    }
}

module.exports = {
  verifyToken,
  verifyAdmin,
};

额外注意事项

  • 给User模型的isAdmin字段添加默认值,避免null值:
// 在User模型的init方法中修改
isAdmin: {
    type: DataTypes.BOOLEAN,
    defaultValue: false // 添加默认值
}
  • 用split(' ')[1]提取Token比replace更可靠,避免因空格数量不一致导致的错误。

内容的提问来源于stack exchange,提问作者Routfin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 00:50:20