Express自定义鉴权中间件无法正确接收传入的targetUserId变量问题
Express中间件变量持久化异常问题解答
问题产生原因
- 你在路由注册阶段就执行了
checkAuth方法生成中间件实例,该方法仅会执行1次,后续所有请求复用的都是它返回的内层异步函数作为处理逻辑。 - 内层函数和外层
checkAuth的作用域形成了闭包,你在代码中直接修改了外层作用域下的targetUserId变量,该变量不会随每次请求重置,会一直保留上一次修改后的值:- 首次请求:
targetUserId初始值为id,赋值为req.params.id即23 - 第二次请求:
targetUserId当前值为23,取req.params['23']自然不存在,赋值为undefined - 第三次及之后请求:
targetUserId为undefined/null,读取req.params对应属性持续返回无效值
- 首次请求:
- 额外注意:你的代码中直接使用了未声明的
allowedUsers变量,也会触发运行时异常。
修复方案
不要直接修改外层作用域的入参变量,在内层中间件中单独声明变量存储读取到的请求参数值即可,修复后代码如下:
const checkAuth = ({ allowedRoles = [], targetUserId, allowedUsers = [] }) => { return async (req, res, next) => { console.log(targetUserId); // 始终为初始传入的字符串,不会被修改 // 权限校验,无权限直接返回403,不要无返回值中断逻辑 if(!allowedRoles.includes(req.user?.role)) { return res.sendStatus(403) } // 单独声明变量存储参数值,不要修改外层入参 const targetId = req.params[targetUserId] if(!allowedUsers.includes(targetId)) { return res.sendStatus(403) } return next(); }; }; app.get( "/activity/:id", checkAuth({ allowedRoles: ["locationAdmin", "orgAdmin"], targetUserId: "id", allowedUsers: [] // 传入你实际的合法用户列表 }), async function (req, res, next) { // 业务逻辑 });
内容的提问来源于stack exchange,提问作者Rusty
相关产品推荐
相关产品推荐

