GraphQL服务器中的授权

p0k*_*k8_ 7 authorization graphql graphql-js relayjs

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

我将通过JWT令牌在每个请求的认证头和后检查的授权用户resolve(),并检查是否有用户在每个角色querymutation

mar*_*ani 11

介绍

首先,一种常见的身份验证方法是使用签名的JWT,其中包含发出请求的用户的id.

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

  • 谁在提出要求?

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

  • 应该执行哪个操作?

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

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

    某些字段只能由某些用户访问.

权限

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

基于角色的权限

在某些应用程序中,基于角色的方法非常有效.例如,对于更简单的Stack Overflow版本,我们可以拥有角色EVERYONE,AUTHENTICATEDMODERATOR.合理的许可规则可能是这样的:

  • EVERYONE 可以阅读问题/答案
    • 请求者:没关系(每个人)
    • 操作:allQuestions,allAnswers查询
    • 领域:text

其他规则(留出参数):*AUTHENTICATED用户可以创建新问题/答案*MODERATOR用户可以创建新问题/答案*MODERATOR用户可以删除问题/答案.

现在,例如,如果有一个未经过身份验证的请求进入请求allQuestions查询,那就没问题,因为我们找到了允许它的权限(第一个).

另一方面,如果对于没有该MODERATOR角色且包含该deleteQuestion突变的用户进行了经过身份验证的请求,则无法找到这些参数的权限.因此请求被拒绝.

图表权限

虽然基于角色的权限已经代表了一个可靠的权限系统,但如果我们想要根据请求者和请求的节点之间的关系等方式授予权限,则它们根本不适合.在我们的示例中,添加简单规则是非常重要的,即允许任何用户删除自己的问题/答案.

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

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

    由节点id确定

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

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

query {
  allAnswers(filter:{
      authorId: $userId,
      id: $nodeId
  }) {
    id
  }
}
Run Code Online (Sandbox Code Playgroud)

对于由GraphQL变量指定的给定节点,用户$userId$nodeId我们使用的查询参数filter要么返回一个空列表,如果该节点没有被当前用户,或一些非空,否则创建.