如何处理GraphQL服务器中的授权?
我应该在每个请求的Authentication头中传递JWT令牌,并在resolve()
之后检查授权用户,并检查用户在每个query
和mutation
上的角色
答案 0 :(得分:11)
首先,您所声明的身份验证的常用方法是使用包含发出请求的用户ID的签名JWT。
现在让我们看看在考虑给定请求的授权时我们可以使用的不同参数。
谁在提出请求?
由上述用户ID确定。可以在数据库中查找有关请求者的更多信息,例如关联的用户角色。这意味着如果我们使用SQL,我们需要维护一个User
表,并在注册时向该表添加新用户。
应该执行哪个操作?
用户可能被授予只读访问权限。某些突变或查询仅允许某些用户使用。
哪些字段包含在查询/变异响应中?
某些字段只能由某些用户访问。
考虑到这些信息,我们可以提出不同的许可系统。最常见的是,在这样的系统中,默认情况下不允许任何操作。当请求进入时,上述参数可以与现有权限匹配,如果找到匹配权限,则授予请求。
在某些应用程序中,基于角色的方法效果很好。
例如,对于更简单的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
返回空列表当前用户,或者其他非空的东西。