如何通过中间件向prisma-typegraphql的GraphQL查询注入参数
解决方案
完全可以实现该需求,无需修改typegraphql-prisma自动生成的resolver,通过全局中间件在请求进入resolver前修改入参即可。以下是两种适配当前技术栈的实现方案:
方案1:使用TypeGraphQL全局中间件(推荐)
该方案直接复用TypeGraphQL的中间件体系,配置成本最低,对原有业务逻辑无侵入:
- 编写全局中间件逻辑
import { MiddlewareFn } from "type-graphql"; export const injectClientIdMiddleware: MiddlewareFn<any> = async ({ context, args, info }, next) => { // 定义需要注入clientId的模型范围 const targetModels = ["Project", "User"]; const operationName = info.fieldName; // 匹配自动生成的resolver操作:比如projects、createProject、updateProject等 const isTargetOperation = targetModels.some(model => operationName.toLowerCase().includes(model.toLowerCase()) ); if (isTargetOperation && context.user?.clientId) { // 注入查询/更新的筛选条件 if (args.where) args.where.clientId = context.user.clientId; // 注入单条创建的参数 if (args.data && !Array.isArray(args.data)) { args.data.clientId = context.user.clientId; } // 适配批量创建操作 if (Array.isArray(args.data)) { args.data = args.data.map(item => ({ ...item, clientId: context.user.clientId })); } } return next(); };
- 注册全局中间件
在buildSchema配置中加入上述中间件即可全局生效:
const schema = await buildSchema({ resolvers: generatedPrismaResolvers, // 替换为你自动生成的resolver集合 globalMiddlewares: [injectClientIdMiddleware], // 其他原有配置 });
方案2:使用GraphQL服务层钩子(可选)
如果你用的是Apollo Server这类服务,也可以通过willSendResponse或者willResolveField钩子实现相同逻辑,和方案1的核心逻辑一致,只是执行时机更靠近服务入口。
安全注意事项
中间件中建议直接强制覆盖参数中的clientId字段,无需保留前端传入的值,避免恶意用户传递其他clientId越权访问或操作数据,全程以身份验证后存入context的用户所属clientId为准。
内容的提问来源于stack exchange,提问作者Thall
相关产品推荐
相关产品推荐

