GraphQL 服务器中的授权

Posted

技术标签:

【中文标题】GraphQL 服务器中的授权【英文标题】:Authorization in GraphQL servers 【发布时间】:2017-05-03 12:47:15 【问题描述】:

如何在 GraphQL 服务器中处理授权?

我是否应该在每个请求的 Authentication 标头中传递 JWT 令牌,并在 resolve() 之后检查授权用户,并检查每个 querymutation 上的用户角色

【问题讨论】:

【参考方案1】:

简介

首先,如您所说,身份验证的常用方法是使用包含发出请求的用户 ID 的签名 JWT。

现在让我们看看在考虑给定请求的授权时可以使用的不同参数

谁提出请求?

由上面提到的用户ID决定。可以在数据库中查找有关请求者的更多信息,例如关联的用户角色。这意味着如果我们使用 SQL 为例,我们需要维护一个User 表,并在注册时将新用户添加到该表中。

应该执行哪个操作?

用户可能被授予只读访问权限。某些突变或查询只允许特定用户使用。

查询/突变响应中包含哪些字段?

某些字段应仅由特定用户访问。

权限

考虑到这些信息,我们可以提出不同的权限系统。最常见的是,在这样的系统中,默认情况下不允许任何操作。当请求进来时,可以将上述参数与现有权限进行匹配,如果找到匹配的权限,则授予请求。

基于角色的权限

在某些应用程序中,基于角色的方法效果很好。 例如,对于更简单的 Stack Overflow 版本,我们可以使用角色 EVERYONEAUTHENTICATEDMODERATOR。一个合理的许可规则可能是这样的:

EVERYONE 可以阅读问题/答案 请求者:没关系(每个人) 操作allQuestionsallAnswers 查询 字段text

其他规则(省略参数): * AUTHENTICATED 用户可以创建新的问题/答案 * MODERATOR 用户可以创建新的问题/答案 * MODERATOR 用户可以删除问题/答案。

现在,例如,如果一个未经身份验证的请求进来,请求 allQuestions 查询,那很好,因为我们找到了允许它的权限(第一个)。

另一方面,如果为不具有MODERATOR 角色且包含deleteQuestion 突变的用户传入经过身份验证的请求,则无法找到这些参数的权限。所以请求被拒绝了。

图表权限

虽然基于角色的权限已经代表了一个可靠的权限系统,但如果我们想让授予权限取决于请求者和被请求节点之间的关系等事情,它们根本不适合。在我们的示例中,添加允许任何用户删除自己的问题/答案的简单规则将是一项相当艰巨的工作。

在Graphcool,我们提出了一种强大但相当简单的方法,我们称之为图形权限来解决这个问题。让我们在检查权限时使以下附加参数可用:

即将访问或修改哪个节点?

由节点id决定

然后我们可以使用 GraphQL 查询针对特殊的权限架构来表达权限,以授予或拒绝节点级别的权限。仅当权限查询包含至少一个不是null 的叶节点时,才会授予对给定节点的访问权限。

在我们的例子中,我们可以指定这个权限查询:

query 
  allAnswers(filter:
      authorId: $userId,
      id: $nodeId
  ) 
    id
  

对于由 GraphQL 变量 $userId$nodeId 指定的给定节点和用户,如果该节点不是由当前用户创建的,我们使用查询参数 filter 返回一个空列表,或者其他非-null 否则。

【讨论】:

以上是关于GraphQL 服务器中的授权的主要内容,如果未能解决你的问题,请参考以下文章

GraphQL + Relay:如何执行重新获取授权?

使用 graphql 订阅和微服务的授权(不是身份验证!)模式

如何使用 Apollo Server 2.0 GraphQL 将模式指令中的信息作为返回的数据包含在内?

使用身份验证的 graphql 模式拼接

Graphql Ruby 中的参数授权

graphql服务器端验证