Strapi中如何限制GraphQL结果仅返回所有者所属数据?
解决Strapi GraphQL接口仅返回所有者数据的问题
你遇到的问题是典型的REST与GraphQL请求结构差异导致的——GraphQL的查询内容并不像REST那样放在ctx.query里,而是封装在POST请求的ctx.request.body中,所以原策略的逻辑自然无法生效。下面给你两种可行的解决方案,按需选择:
方案一:修改策略兼容REST与GraphQL
直接调整原策略代码,针对不同请求类型做适配处理:
module.exports = async (ctx, next) => { const { id, role } = ctx.state.user; // 管理员不受限制,直接放行 if (role === 'administrator') { await next(); return; } // 处理REST请求(保留原逻辑) if (ctx.request.method === 'GET' && ctx.query) { ctx.query.owner = id; } // 处理GraphQL请求 if (ctx.request.method === 'POST' && ctx.request.body.query) { const { query, variables } = ctx.request.body; // 匹配GraphQL的列表查询(如findManyXXX),自动追加owner过滤条件 const updatedQuery = query.replace( /findMany(\w+)\((.*?)\)/g, (match, type, args) => { const hasWhere = args.includes('where:'); // 已有where条件则追加owner,否则新增where规则 if (hasWhere) { return `findMany${type}(${args.replace(/where:({.*?})/, `where: {...$1, owner: "${id}"}`)})`; } else { return `findMany${type}(${args ? `${args}, ` : ''}where: {owner: "${id}"})`; } } ); // 更新请求体中的查询内容 ctx.request.body.query = updatedQuery; } await next(); };
说明:
- 通过请求方法和请求体特征区分REST/GraphQL请求
- 用正则表达式匹配常见的
findMany列表查询,自动注入所有者过滤规则 - 保留了原REST请求的处理逻辑,实现一次配置兼容两种接口
方案二:使用生命周期钩子(更优雅推荐)
Strapi的模型生命周期钩子可以统一处理数据查询的过滤逻辑,不管是REST还是GraphQL请求都会生效,无需区分请求类型:
// 在目标模型的生命周期文件中(路径示例:./api/[你的模型名]/models/[你的模型名].js) module.exports = { lifecycles: { // 处理单条数据查询 async beforeFind(ctx) { const { user } = ctx.state; if (user && user.role !== 'administrator') { ctx.params.where = { ...ctx.params.where, owner: user.id }; } }, // 处理多条数据查询 async beforeFindMany(ctx) { const { user } = ctx.state; if (user && user.role !== 'administrator') { ctx.params.where = { ...ctx.params.where, owner: user.id }; } } } };
这种方式无需修改请求内容,直接在数据查询前注入过滤条件,逻辑更清晰,也更符合Strapi的设计规范,推荐优先使用。
内容的提问来源于stack exchange,提问作者Yen Sheng
相关产品推荐
相关产品推荐

