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
热门API
- 1. AI文本生成
- 2. AI图片生成_文生图
- 3. AI图片生成_图生图
- 4. AI图像编辑
- 5. AI视频生成_文生视频
- 6. AI视频生成_图生视频
- 7. AI语音合成_文生语音
- 8. AI文本生成(中国)
最新文章
- 什么是 OpenReview
- Vue中使用echarts@4.x中国地图及AMap相关API的使用
- 使用 Zeplin API 实现 Zeplin 移动化
- Rest API 教程 – 完整的初学者指南
- API Key 密钥 vs OAuth 2.0:身份认证的比较
- Claude API 能使用 OpenAI 接口协议吗?
- 使用DeepSeek R1、LangChain和Ollama构建端到端生成式人工智能应用
- 如何获取通义千问 API Key 密钥(分步指南)
- 您需要了解的OpenAI Assistants API功能 – PageOn.ai
- DRF库详解:用Django轻松搭建功能强大的API服务
- 一文搞懂在 HTTP 如何 one-api 调用,实操指南来袭!
- 探索海洋数据的宝库:Amentum海洋数据探测API的潜力