【问题标题】:GraphQL skip/access on FIELD_DEFINITION, RBAC for fields?GraphQL 跳过/访问 FIELD_DEFINITION,RBAC 字段?
【发布时间】:2020-08-05 17:05:34
【问题描述】:

让我们想象一下在 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

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

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

【问题讨论】:

  • 适用于其他不可为空的字段?如果字段被保护不应该是可请求的(可以为空或不在查询中使用)......如果条件不满足,你应该抛出访问错误......如果用户没有权限,客户端(应用程序)不应该要求这个字段
  • @xadm 我的想法不同:你可以打电话,但我没有显示(如果不是所有要求都满足的话)。但最后,我认为graphql技术的实际实施是不可能的。我会针对不同的调用使用不同的类型
  • 如果您可以调用,那么您必须为不可为空(使用! 键入)字段返回一些(非空)值(您不能按需更改类型,否则服务器将抛出错误' null 表示不可为空')。 - 返回 FAKE - 如果假的(在客户端检测)不显示?但是如果您使用 const 作为数组中项目的 id 会导致客户端缓存错误...返回超过某个限制的随机数?恕我直言,不应该被请求,客户应该意识到这一点(不难实施)。

标签: graphql


【解决方案1】:

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

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

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

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

【讨论】:

    猜你喜欢
    • 2021-02-23
    • 2021-10-15
    • 2019-02-19
    • 2016-03-13
    • 2021-11-17
    • 1970-01-01
    • 2019-04-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多