首页 > 解决方案 > graphql-shield 作为 Postgraphile 中的“makeProcessSchemaPlugin”

问题描述

尝试过 postgrphile 示例,但不确定在哪里出错?

我正在尝试将 graphql-shield 实现为插件

    middlewarePlugin = makeProcessSchemaPlugin((schema: typeof GraphQLSchema) => {
        return applyMiddleware(schema, permissions);
    });

权限.ts

const { rule, shield } = require("graphql-shield");

const isAuthenticated = rule()((parent: any, args: any,  user: any ) => {
    return user !== null;
});

const permissions = shield({
    Query: {
        viewer: isAuthenticated
    }
});

export = permissions;

我将 middlewarePlugin 作为 postgraphile 中的其他插件导入:

  appendPlugins: [
            myClass.myPlugin,
            myClass.jsonPlace,
            myClass.middlewarePlugin
        ],

崩溃日志:

| 构建初始架构时发生严重错误。退出是因为retryOnInitFail未设置。错误详情:graphql | 图ql | 类型错误:无法读取未定义 graphql 的属性“片段”| 在 isMiddlewareWithFragment (/home/node/app/node_modules/graphql-middleware/src/utils.ts:25:17) graphql | 在 Object.isMiddlewareFunction (/home/node/app/node_modules/graphql-middleware/src/utils.ts:33:10) graphql | 在 Object.validateMiddleware (/home/node/app/node_modules/graphql-middleware/src/validation.ts:9:7) graphql | 在 addMiddlewareToSchema (/home/node/app/node_modules/graphql-middleware/src/middleware.ts:33:27) graphql | 在 normalisedMiddlewares.reduceRight.schema.schema (/home/node/app/node_modules/graphql-middleware/src/middleware.ts:91:11) graphql | 在阵列。reduceRight() 在 applyMiddlewareWithOptions (/home/node/app/node_modules/graphql-middleware/src/middleware.ts:80:77) graphql | 在 applyMiddleware (/home/node/app/node_modules/graphql-middleware/src/middleware.ts:132:10) graphql | 在钩子 (/home/node/app/resolvers/test.resolver.ts:254:16) graphql | 在 SchemaBuilder.applyHooks (/home/node/app/node_modules/graphile-build/src/SchemaBuilder.js:398:20)

标签: postgraphile

解决方案


postgraphile 期望的中间件类型与 graphql-middleware 略有不同。我没有下载graphql-middlewaregraphql-shield试图让它们与 postgraphile 一起工作,而是最终用 makeWrapResolversPlugin 编写了我自己的“盾牌。例子:

const filter = (ctx) => {
  // Only attempting to do auth for non-root things, because
  // with postgraphile, all the data gets fetched at the root
  if (ctx.scope.isRootMutation || ctx.scope.isRootQuery) {
    // return this to make it available to the wrapper function
    return ctx.scope.fieldName
  }
  // return null to not wrap this non-root resolver
  return null
}

const wrapper = (fieldName) => 
  async (resolve, source, args, context) => {
    // Unless we're doing createUser, do an auth check

    // 
    if (fieldName === "createUser") return resolve()

    const isAuthenticated = await getIsAuthenticated(context)

    // 
    if (isAuthenticated) return resolve()

    throw new Error("Unauthorized");
  }

const Permissions = makeWrapResolversPlugin(filter, wrapper)

推荐阅读