如何使用Mongoose查询用户权限数组中的指定eventId?
问题分析与解决方案
你的查询失效主要有两个核心问题:类型不匹配和查询操作符误用,以下是具体修正方案:
1. 核心错误点
- $in操作符误用:
$in用于匹配字段值在指定数组中的场景,但你这里的eventId是单个值,不需要用$in,直接使用相等匹配即可。 - ObjectId类型转换:
req.params.id是字符串类型,而你的Schema中permissions.eventId定义为mongoose.Schema.Types.ObjectId,直接用字符串匹配会失败,必须手动转换类型。 - 查询方法选择:
User.find()会返回符合条件的用户数组,你仅需验证当前用户是否拥有目标权限,使用User.findOne()更高效,返回结果为单个文档或null,便于直接判断权限是否存在。
2. 修正后的中间件代码
const mongoose = require('mongoose'); const authorization = async (req, res, next) => { try { // 将字符串id转换为ObjectId类型 const eventId = new mongoose.Types.ObjectId(req.params.id); const token = req.headers.authorization.split(' ')[1]; const tokenDecoded = jwt.verify(token, process.env.JWT_SECRET); const userId = tokenDecoded.id; // 查询当前用户是否拥有该事件的权限 const hasPermission = await User.findOne({ _id: userId, 'permissions.eventId': eventId }); // 无权限则直接返回403 if (!hasPermission) { return res.status(403).json({ message: '无访问该事件的权限' }); } next(); } catch (error) { // 区分Token错误和其他异常 if (error.name === 'JsonWebTokenError') { return res.status(401).json({ message: 'Token无效' }); } res.status(500).json({ message: '权限验证失败' }); } }
3. 额外优化建议
- 给
permissions.eventId添加索引,提升数组字段的查询效率:permissions: [{ eventId: { type: mongoose.Schema.Types.ObjectId, required: false, ref: 'Event', index: true // 添加索引 }, role: { type: String, required: false } }] - 如果需要同时验证角色(比如仅允许管理员访问),可以用
$elemMatch扩展查询条件:const hasPermission = await User.findOne({ _id: userId, 'permissions': { $elemMatch: { eventId: eventId, role: 'admin' // 指定需要验证的角色 } } });
内容的提问来源于stack exchange,提问作者Segev Solomon
相关产品推荐
相关产品推荐

