当前位置: 首页 > 知识库问答 >
问题:

GraphQL中继:如何执行重新蚀刻的授权?

东郭凯捷
2023-03-14

我正在使用Express构建GraphQL服务器,并试图支持中继。

对于常规的GraphQL查询,我可以在解析函数中处理授权。例如:

var queryType = new GraphQLObjectType({
    name: 'RootQueryType',
    fields: () => ({
        foo: {
            type: new GraphQLList(bar),
            description: 'I should have access to some but not all instances of bar',
            resolve: (root, args, request) => getBarsIHaveAccessTo(request.user)
        }
    })
});

为了在后端支持中继重蚀刻,Facebook的中继教程指导我们让GraphQL对象实现一个节点接口,用于将全局ID映射到对象,并将对象映射到GraphQL类型。节点接口由graphql中继中的nodeDefinitions函数定义。

const {nodeInterface, nodeField} = nodeDefinitions(
    (globalId) => {
        const {type, id} = fromGlobalId(globalId);
        if (type === 'bar') {
            // since I don't have access to the request object here, I can't pass the user to getBar, so getBar can't perform authorization
            return getBar(id);
        } else {
            return null;
        }
    },
    (obj) => {
        // return the object type
    }
);

传递给nodeDefinitions的重新蚀刻函数不会传递请求对象,而只传递全局id。如何在重新蚀刻期间访问用户,以便授权这些请求?

作为一项健全性检查,我尝试通过节点接口查询经过身份验证的用户无权(也不应该)访问的节点,并获得了请求的数据:

{node(id:"id_of_something_unauthorized"){
    ... on bar {
        field_this_user_shouldnt_see
    }
}}

=

{
    "data": {
        "node": {
            "field_this_user_shouldnt_see": "a secret"
        }
    }
}

共有1个答案

江永安
2023-03-14

事实证明,请求数据实际上是传递给解析的。如果我们查看源代码,就会看到nodedeDefinitions抛出parent参数,并从nodeField的resolve函数传递全局idcontext(包含请求数据)和info参数。

最终,resolve调用将获得以下参数:

(parent, args, context, info)

idFetcher将获得:

(id, context, info)

所以我们可以如下实现授权:

const {nodeInterface, nodeField} = nodeDefinitions(
    (globalId, context) => {
        const {type, id} = fromGlobalId(globalId);
        if (type === 'bar') {
            // get Bar with id==id if context.user has access
            return getBar(context.user, id);
        } else {
            return null;
        }
    },
    (obj) => {
        // return the object type
    }
);

https://github.com/graphql/graphql-relay-js/blob/master/src/node/node.js#L94-L102

 类似资料:
  • 我将angular2与angular2 fullcalendar一起使用。在我的项目中,我从后端获取数据。现在我的问题是,当我使用选择日期添加事件时,我希望它在日历上显示成功提交数据,而无需重新加载页面。以前我使用的是

  • 目前,我正在从这里学习sangria-graphql。然而,我找不到任何关于突变(添加,更新,删除)的文档。还有,谷歌也不会帮我多少。你们能给我提供什么好的资源吗?

  • 我正在努力让普里斯玛和继电器工作。这是我的回购协议: https://github.com/jamesmbowler/prisma-relay-todo 这是一个简单的待办事项列表。我可以添加待办事项,但用户界面不会更新。当我刷新时,待办事项就在那里。 我能找到的所有更新存储的示例都对正在更新/创建的对象使用“父”。 看https://facebook.github.io/relay/docs/e

  • 问题内容: 我有一个页面正在从第三方(新闻提要)加载脚本。脚本的url在加载时动态分配(根据第三方代码)。 然后从中加载的脚本创建并加载具有新闻提要中各种内容的元素,并以漂亮的格式等将元素加载到其中(传入ID“ div1287”,以便脚本知道在何处加载内容)。 唯一的问题是,它只会加载一次。我希望它每n秒重新加载一次(从而显示新内容)。 所以,我想我会尝试一下: div清除后,我得到警报,但是没有

  • 我是GraphQL的新手。我已经有了一个添加数据的模式和变异,但是我有点纠结于如何进行更新变异来更新数据库中的现有数据。 我想我知道我可能需要做些什么来实现这一点,但我会感谢一些关于我的想法是否是正确的方法的指示。 这是我的模式,其中包含我的突变GraphQLObject。 我是否正确地说,在解析函数中,我需要首先通过id在数据库中找到相关对象,然后返回任何arg已更新/更改的args?我不知道如

  • 我正在使用Jooq和GradleJooq插件生成代码。它工作得很好,但在添加表或删除列时,我在更新生成的代码时遇到了一个问题。我可以通过更改“packageName”配置参数来强制更新,并构建一个新的包。通过返回原始名称,代码按预期进行了更新。 在使用我的设置更改模式后,重新生成代码的正确方法是什么? 我正在使用https://github.com/etiennestuder/gradle-joo

  • 问题内容: 我对Quartz有点陌生。有没有一种方法可以更新已经提交的Quartz作业的作业执行间隔?这个间隔会立即更新吗?重新安排工作后,您是否必须再次开始工作? 我找到了以下链接,但由于我的石英罐不包含该链接中使用的某些类,因此我不知道代码所引用的库。另外,triggerKey方法从何而来?这是静态导入吗? http://www.quartz- scheduler.org/documentat

  • 我希望在我的一个JUnit测试用例中将作业执行间隔更新为一个非常大的数字,因为我不希望作业干扰被测试类的状态。一旦测试用例完成,我希望将作业执行间隔重置为将在生产中使用的实际值