GraphQL 服务器中的授权
Authorization in GraphQL servers
如何在 GraphQL 服务器中处理授权?
我应该在每个请求的身份验证 header 中传递 JWT 令牌并在 resolve()
之后检查授权用户并在每个 query
和 mutation
简介
首先,如您所述,身份验证 的常用方法是使用包含发出请求的用户 ID 的签名 JWT。
现在让我们看看在考虑给定请求的授权时我们可以使用的不同参数。
谁在提出请求?
由上述用户id决定。可以在数据库中查找有关请求者的更多信息,例如关联的用户角色。这意味着如果我们使用 SQL,我们需要维护一个 User
table,并在注册时向此 table 添加新用户。
应该执行哪个操作?
用户可能被授予只读访问权限。某些变更或查询只允许某些用户使用。
query/mutation 响应中包含哪些字段?
某些字段只能由某些用户访问。
权限
考虑到这些信息,我们可以想出不同的权限系统。最常见的是,在这样的系统中,默认情况下不允许进行任何操作。当一个请求进来时,可以将上面提到的参数与现有的权限进行匹配,如果找到匹配的权限,则请求被授予。
基于角色的权限
在某些应用程序中,基于角色的方法效果很好。
例如,对于 Stack Overflow 的更简单版本,我们可以使用角色 EVERYONE
、AUTHENTICATED
和 MODERATOR
。一个合理的许可规则可能是这样的:
EVERYONE
可以阅读 questions/answers
- 请求者:无所谓(大家)
- 操作:
allQuestions
、allAnswers
查询
- 字段:
text
其他规则(省略参数):
* AUTHENTICATED
用户可以创建新的 questions/answers
* MODERATOR
用户可以创建新的 questions/answers
* MODERATOR
用户可以删除 questions/answers.
现在,例如,如果收到未经身份验证的请求,请求 allQuestions
查询,那很好,因为我们找到了允许它的权限(第一个)。
另一方面,如果针对没有 MODERATOR
角色且包含 deleteQuestion
突变的用户发出经过身份验证的请求,则找不到这些参数的权限.所以请求被拒绝了。
图表权限
虽然基于角色的权限已经代表了一个可靠的权限系统,但如果我们想根据请求者和被请求节点之间的关系来授予权限,它们根本不适合。在我们的示例中,添加允许任何用户删除他们自己的 questions/answers.
的简单规则将是一项相当大的工作。
在 Graphcool,我们提出了一种强大但相当简单的方法,我们称之为 图形权限 来解决这个问题。让我们在检查权限时提供以下额外的参数:
即将访问或修改哪个节点?
由节点id决定
然后我们可以使用 GraphQL 查询针对特殊的 权限模式 来表达权限,以在节点级别授予或拒绝权限。仅当权限查询包含至少一个不是 null
.
的叶节点时,才允许访问给定节点
在我们的例子中,我们可以指定这个权限查询:
query {
allAnswers(filter:{
authorId: $userId,
id: $nodeId
}) {
id
}
}
对于由 GraphQL 变量 $userId
和 $nodeId
指定的给定节点和用户,我们使用查询参数 filter
到 return 如果节点是空列表不是由当前用户创建的,或者不是由其他用户创建的。
如何在 GraphQL 服务器中处理授权?
我应该在每个请求的身份验证 header 中传递 JWT 令牌并在 resolve()
之后检查授权用户并在每个 query
和 mutation
简介
首先,如您所述,身份验证 的常用方法是使用包含发出请求的用户 ID 的签名 JWT。
现在让我们看看在考虑给定请求的授权时我们可以使用的不同参数。
谁在提出请求?
由上述用户id决定。可以在数据库中查找有关请求者的更多信息,例如关联的用户角色。这意味着如果我们使用 SQL,我们需要维护一个
User
table,并在注册时向此 table 添加新用户。应该执行哪个操作?
用户可能被授予只读访问权限。某些变更或查询只允许某些用户使用。
query/mutation 响应中包含哪些字段?
某些字段只能由某些用户访问。
权限
考虑到这些信息,我们可以想出不同的权限系统。最常见的是,在这样的系统中,默认情况下不允许进行任何操作。当一个请求进来时,可以将上面提到的参数与现有的权限进行匹配,如果找到匹配的权限,则请求被授予。
基于角色的权限
在某些应用程序中,基于角色的方法效果很好。
例如,对于 Stack Overflow 的更简单版本,我们可以使用角色 EVERYONE
、AUTHENTICATED
和 MODERATOR
。一个合理的许可规则可能是这样的:
EVERYONE
可以阅读 questions/answers- 请求者:无所谓(大家)
- 操作:
allQuestions
、allAnswers
查询 - 字段:
text
其他规则(省略参数):
* AUTHENTICATED
用户可以创建新的 questions/answers
* MODERATOR
用户可以创建新的 questions/answers
* MODERATOR
用户可以删除 questions/answers.
现在,例如,如果收到未经身份验证的请求,请求 allQuestions
查询,那很好,因为我们找到了允许它的权限(第一个)。
另一方面,如果针对没有 MODERATOR
角色且包含 deleteQuestion
突变的用户发出经过身份验证的请求,则找不到这些参数的权限.所以请求被拒绝了。
图表权限
虽然基于角色的权限已经代表了一个可靠的权限系统,但如果我们想根据请求者和被请求节点之间的关系来授予权限,它们根本不适合。在我们的示例中,添加允许任何用户删除他们自己的 questions/answers.
的简单规则将是一项相当大的工作。在 Graphcool,我们提出了一种强大但相当简单的方法,我们称之为 图形权限 来解决这个问题。让我们在检查权限时提供以下额外的参数:
即将访问或修改哪个节点?
由节点id决定
然后我们可以使用 GraphQL 查询针对特殊的 权限模式 来表达权限,以在节点级别授予或拒绝权限。仅当权限查询包含至少一个不是 null
.
在我们的例子中,我们可以指定这个权限查询:
query {
allAnswers(filter:{
authorId: $userId,
id: $nodeId
}) {
id
}
}
对于由 GraphQL 变量 $userId
和 $nodeId
指定的给定节点和用户,我们使用查询参数 filter
到 return 如果节点是空列表不是由当前用户创建的,或者不是由其他用户创建的。