Strapi V4:如何通过中间件隐藏用户接口中的邮箱?
问题解答
1. 是否必须保留await next()?
不需要,甚至在你的当前逻辑下不能加,原因如下:
- 你在中间件里手动调用了
controller.findOne(ctx),已经完成了原本路由handler(user.findOne)的查询工作,并修改了ctx.body隐藏邮箱。 - 调用
await next()后,Strapi会继续执行路由链条的后续逻辑——也就是原本的user.findOnehandler,它会重新查询用户数据并覆盖你修改后的ctx.body,导致邮箱再次出现。
如果想遵循中间件链式逻辑(不手动调用控制器),可以调整写法,改为在next()之后修改响应:
export default (config, { strapi })=> { return async (ctx, next) => { await next(); // 先执行原handler完成数据查询 const data = ctx.body; if (data){ const authUserId = ctx.state.user?.id; const isMe = (authUserId === data.id); if (!isMe){ delete data.email; } ctx.body = data; } } }
这种写法既符合中间件的链式执行逻辑,又能在响应返回前完成邮箱隐藏操作。
2. 如何调试找出覆盖输出的函数?
- 打印路由中间件列表:在
strapi-server.js中打印目标路由的所有中间件,确认后续执行的逻辑:apiRoutes.filter(route => route.handler === 'user.findOne').map(route => { console.log('当前路由的中间件:', route.config.middlewares); route.config.middlewares = [...(route.config.middlewares || []), 'plugin::spiff.user-find-one']; return route; }); - 给响应打跟踪标记:在你修改
ctx.body后添加唯一标识,next()后打印ctx.body判断是否被重新赋值:// 修改后添加标记 data._customModified = true; ctx.body = data; await next(); console.log('next执行后的body:', ctx.body); // 查看_customModified是否存在,判断响应是否被覆盖 - 启用Strapi调试日志:在
config/server.js中设置日志级别为debug,查看完整请求处理流程:
启动Strapi后,日志会输出所有中间件和handler的执行顺序,可定位到修改响应的环节。module.exports = ({ env }) => ({ // 其他配置 logger: { level: 'debug', }, }); - 用Node.js调试器断点跟踪:在中间件的
await next()前添加debugger语句,启动Strapi时执行node --inspect ./node_modules/@strapi/strapi/bin/strapi.js develop,再用VSCode或Chrome DevTools attach到进程,逐步跟踪next()执行后修改ctx.body的代码。
内容的提问来源于stack exchange,提问作者gordie
相关产品推荐
相关产品推荐

