首页 > 解决方案 > GraphQL 跳过/访问 FIELD_DEFINITION,RBAC 字段?

问题描述

让我们想象一下在 graphql 中有一个简单的类型

type Coupon {
    id: ID!
    code: String!
}

仅当用户具有确定的条件时,我才希望显示 id 字段。然后我将创建一个指令

directive IncludeWhen(cond: String!) on FIELD_DEFINITION

并将代码编辑为

type Coupon {
    id: ID! @IncludeWhen(cond: "ADMIN")
    code: String!
}

如果用户具有必要的权限,我将检查指令解析器:

export class IncludeWhenDirective extends SchemaDirectiveVisitor {
    public visitFieldDefinition(field) {
        const { resolve = defaultFieldResolver } = field;

        const requiredCond = this.args.cond;

        field.resolve = async function (...args) {
            const context = args[2];
            const currentUser = context.currentUser;

            let result;

            if (currentUser.hasCond(requiredCond) {
                throw new AuthenticationError();
                result = await resolve.apply(this, args);
            }

            return result;
        };
    }
}

好吧,这是错误的。端点返回一个错误,如

Cannot return null for non-nullable field Coupon.ID

在没有必要条件的情况下向用户查询时。

是否可以完全跳过该字段?也许访问解析器并删除字段而不破坏整个过程?

标签: graphql

解决方案


最后,我提出的整个问题都是错误的,而不仅仅是代码。

背后的逻辑有缺陷,我无法以这种方式操纵输出。正如@xadm 建议的那样,我要感谢他/她指出我正确的方式,我将在球场上放置一名“警卫”。如果不满足要求,则整个查询将失败。

即使禁用了自省,也有人可以尝试“猜测”一个类型上存在哪些其他字段。如果有人试图在没有必要条件的情况下访问字段,则通过失败来保护查询是正确的方法。

对于其他情况,IE基于不同条件的不同输出将覆盖例如工厂模式。


推荐阅读