如何处理 GraphQL 服务器中的授权?
我是否应该在每个请求的 Authentication header 中传递 JWT token 并在 resolve()
之后检查授权用户?并检查每个 query
上用户的角色和 mutation
最佳答案
介绍
首先,正如您所说的,一种常见的身份验证方法是使用包含发出请求的用户的 ID 的签名 JWT。
现在让我们看看在考虑给定请求的授权时我们可以使用的不同参数。
由上面提到的用户 id 确定。可以在数据库中查找有关请求者的更多信息,例如关联的用户角色。这意味着我们需要维护一个
User
例如,如果我们使用 SQL,并在注册时将新用户添加到该表中。 用户可能被授予只读访问权限。某些更改或查询仅允许某些用户使用。
某些字段只能由某些用户访问。
权限
考虑到这些信息,我们可以想出不同的权限系统。最常见的是,在这样的系统中,默认情况下不允许任何操作。当请求进来时,可以将上述参数与现有权限进行匹配,如果找到匹配的权限,则授予该请求。
基于角色的权限
在某些应用程序中,基于角色的方法效果很好。
例如,对于更简单的 Stack Overflow 版本,我们可以拥有角色
EVERYONE
, AUTHENTICATED
和 MODERATOR
.一个合理的权限规则可能是这样的:EVERYONE
可以阅读问题/答案allQuestions
, allAnswers
查询 text
其他规则(不包括参数):
*
AUTHENTICATED
用户可以创建新的问题/答案*
MODERATOR
用户可以创建新的问题/答案*
MODERATOR
用户可以删除问题/答案。现在例如,如果一个未经身份验证的请求进来,它要求
allQuestions
查询,这很好,因为我们找到了允许它的权限(第一个)。另一方面,如果经过身份验证的请求来自没有
MODERATOR
的用户。角色并包括 deleteQuestion
突变,没有找到这些参数的权限。所以请求被拒绝。图权限
虽然基于角色的权限已经代表了一个可靠的权限系统,但如果我们想让授予权限依赖于请求者和被请求节点之间的关系之类的东西,它们根本不适合。在我们的示例中,添加允许任何用户删除他们自己的问题/答案的简单规则将是一项艰巨的工作。
在 Graphcool ,我们提出了一个强大而相当简单的方法,我们称之为 图权限来解决这个问题。让我们做以下附加参数 检查权限时可用:
由节点 ID
然后我们可以使用针对特殊 的 GraphQL 查询来表达权限。权限架构 在节点级别授予或拒绝权限。仅当权限查询包含至少一个不是
null
的叶节点时,才允许访问给定节点。 .在我们的例子中,我们可以指定这个权限查询:
query {
allAnswers(filter:{
authorId: $userId,
id: $nodeId
}) {
id
}
}
对于 GraphQL 变量指定的给定节点和用户
$userId
和 $nodeId
,我们使用查询参数 filter
如果节点不是由当前用户创建的,则返回一个空列表,否则返回一个非空的列表。
关于GraphQL 服务器中的授权,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41206123/