GraphQL 授权层的复杂性及 Hasura 的解决方案
构建授权层是GraphQL API 编写授权逻辑更加复杂。在本文中,我们将探讨如何为自定义 GraphQL 服务器构建授权逻辑,并分析其复杂性来源。同时,我们还会比较 Hasura 的解决方案,了解其如何通过声明式方法和谓词下推技术简化授权逻辑的实现。
数据建模
数据建模是构建授权系统的基础。它定义了数据类型及其关系,从而决定了授权系统的设计方式。
例如,一个应用允许用户查看所有用户的公共数据以及他们的私人数据。此时,数据模型需要包含相关的表列和与私人数据相关的关系。
角色和属性
授权系统的建模通常采用两种方法:
通过定义角色和属性,可以为应用程序设计灵活的授权规则。
嵌套规则
GraphQL 查询可能涉及多个嵌套字段,这些字段可能跨越多个数据源。授权逻辑需要在上下文中动态应用到所有嵌套级别。
例如,以下查询中,授权规则需要同时适用于用户和订单:
query {
用户 {
id
名称
订单 {
id
order_total
}
}
}
这种嵌套规则的实现增加了授权逻辑的复杂性。
性能优化与谓词下推
授权检查不应显著增加响应延迟。然而,在自定义 GraphQL 服务器中,授权检查通常在数据获取之后进行,这可能导致额外的数据处理,降低性能。
谓词下推 是一种优化方法,它将授权规则直接应用到数据库查询中。例如,在电子商务应用中,仅查询当前用户的订单数据。这种方法不仅更高效,还能提升安全性。
为什么构建授权层很复杂?
在自定义 GraphQL 服务器中,授权逻辑的实现方式多种多样,包括:
- API 范围的授权:在请求级别应用规则。
- 基于解析器的授权:在解析器内实现授权逻辑。
- 基于模式/模型的授权:授权逻辑依赖于 GraphQL 模式。
如果每个字段都需要授权规则,基于解析器的授权会导致大量样板代码,难以维护。而基于模式的授权则更灵活,但也需要额外的设计和实现。
使用上下文构建授权逻辑
GraphQL 中的授权通常通过 Context 对象实现。上下文对象在每次请求时创建,并传递给每个解析器,包含用户身份验证和授权信息。
解析和验证 JWT 令牌
JWT(JSON Web Token)是常见的身份验证方式。以下是解析和验证 JWT 令牌的示例代码:
try {
if (token) {
return jwt.verify(token, YOUR_SECRET_KEY);
}
return null;
} catch (err) {
return null;
}
传递上下文
在解析器中,授权逻辑可以通过上下文对象实现。例如:
users: (parent, args, contextValue) => {
if (!contextValue.user) return null;
return ['bob', 'jake'];
};
基于 GraphQL 模式的授权
对于复杂的授权需求,可以基于 GraphQL 模式定义规则。例如,允许用户仅访问自己的数据:
const CanPublishPost = preExecRule(async (context, fieldArgs) => {
const graphQLResult = await graphql({
schema: context.schema,
source: `query post($postId: ID!) {
post(id: $postId) {
author {
id
}
}
}`,
variableValues: { postId: fieldArgs.postId },
});
const post = graphQLResult.data?.post;
return post && post.author.id === context.user?.id;
});
Hasura 的声明式授权解决方案
Hasura 提供了一个强大的授权引擎,通过声明式方法简化授权逻辑的实现。
声明式授权
Hasura 允许开发者通过元数据配置声明角色及其权限。这种方法更易于创建、维护和审计。
细粒度访问控制
Hasura 支持基于角色的访问控制,权限规则可应用于所有 CRUD 操作。每个角色都会生成一个特定的 GraphQL 模式,表示该角色可访问的查询和字段。
授权规则可以基于以下条件:
- 数据关系属性
- 用户属性
- 数据模型的部分屏蔽或标记
谓词下推
Hasura 自动将授权规则下推到数据库查询中,从而避免额外的数据处理,提高性能。
跨源授权
Hasura 支持跨数据源的授权规则整合。通过将解析后的值作为标头转发到外部服务,可以轻松在外部服务中应用授权规则。
总结
构建 GraphQL API 的授权层是一项复杂的任务,涉及数据建模、角色定义、嵌套规则、性能优化等多个方面。Hasura 提供了一种声明式的解决方案,通过细粒度访问控制和谓词下推技术,显著简化了授权逻辑的实现。对于开发者而言,Hasura 是一种高效且安全的选择。
原文链接: https://hasura.io/blog/the-complexity-of-building-a-graphql-api-permissions-layer-and-how-hasura-solves-this
最新文章
- 2025年适合您项目的API框架类型 – Aloa
- 使用缓存策略提高 API 性能
- 什么是API加密?
- 微博热搜API的免费调用教程
- 13 种可靠的货币兑换 API
- 共享单车数据获取:网络抓取与API调用实践指南
- ChatGPT生态系统的安全漏洞导致第三方网站账户和敏感数据泄露
- Flask-RESTful:最强Python Web服务框架,轻松构建REST API
- 商品比价API:如何让购物决策变得轻松又智能?
- 构建更智能的搜索:面向开发者的Anthropic AI API – Just Think AI
- 基于N-API和node-addon-api的Node.js异步C++扩展
- 理解每种API类型的基本指南