如何使用 AppSync GraphQL 转换为双向一对多 @connection 执行字段级别 @auth?
Posted
技术标签:
【中文标题】如何使用 AppSync GraphQL 转换为双向一对多 @connection 执行字段级别 @auth?【英文标题】:How to do field level @auth for bi-directional one-to-many @connection with AppSync GraphQL Transform? 【发布时间】:2019-11-11 12:59:46 【问题描述】:我正在尝试弄清楚如何在现场级别保护一对多 @connection
和 @auth
免受不应允许的突变。 (即:拒绝特定用户运行突变,最终以另一个用户的身份插入帖子。)
从在字段级别保护突变的示例开始:https://aws-amplify.github.io/docs/cli/graphql#field-level-authorization
我试着做这样的事情:
type User @model @auth(rules: [ allow: owner, ownerField: "id" ])
id: ID!
posts: [Post]
@connection(name: "UserPosts")
@auth(rules: [ allow: owner, ownerField: "id" ])
type Post @model
title: String!
user: User!
@connection(name: "UserPosts")
@auth(rules: [ allow: owner, ownerField: "userPostId" ])
然后说已经有一个 id 为regular-user-id
的用户
显然,我的身份验证规则不会阻止其他用户,例如使用 id 为:malicious-user-id
来运行此突变:
mutation
createPost(input:
title:"Oh this is BAD!"
postUserId: "regular-user-id"
)
title
运行一个简单的查询以确保这确实发生了:
query
getUser(id:"regular-user-id")
posts
items
title
=>
"data":
"getUser":
"posts":
"items": [
"title": "Regular User title"
,
"title": "Oh this is BAD!"
,
]
我尝试了各种方法来解决这个问题,但找不到任何有关双向字段级别身份验证的文档。我对 AppSync 还很陌生,所以我想我一定没有得到任何东西,但这是如此常见的用例场景,我真的很惊讶没有更多关于它的文档。
我们将不胜感激。
【问题讨论】:
【参考方案1】:要保护Mutation.createPost
突变,以便只有通过postUserId
指定的帖子的所有者才能访问它,您可以在帖子对象定义中添加@auth 指令:
type Post @model @auth(rules: [ allow: owner, ownerField: "postUserId" ])
title: String!
# This will use a field 'postUserId' by default.
user: User!
@connection(name: "UserPosts")
有了这个设置,一个突变:
mutation
createPost(input:
title:"Oh this is BAD!"
postUserId: "regular-user-id"
)
title
如果登录用户不是“regular-user-id”,则会失败。
这个答案也可能有助于填写内容https://github.com/aws-amplify/amplify-cli/issues/1507#issuecomment-513042021。
【讨论】:
【参考方案2】:恶意用户应该能够更新Post
标题吗?我知道这不是您问题的确切答案,因为您专注于关系领域,但是通过尝试了解如何自己做这些事情,我阅读了一些关于引入某种形式的“每个人”组的内容因此您可以为非所有者的用户定义身份验证。然后,您可以在整个 Post
模型上添加身份验证,这样只有所有者才能更新任何字段;
type Post
@model
@auth(rules: [
allow: owner, ownerField: "userPostId" ,
allow: groups, groups: ["everyone"], operations: [read]
])
title: String!
user: User!
@connection(name: "UserPosts")
我是一个超级新手(我目前正在评估是否将它用于我正在开始的项目),所以我在这里可能完全错了。如果您确实想要一个只有参考字段具有身份验证的半开放模型,我不知道该怎么做:(
【讨论】:
帖子创建后不更新。这很好用。创建帖子是问题所在。我找不到阻止说 UserB 运行突变的方法,他指定帖子属于另一个用户说 UserA。 ownerField 将是“postUserId”而不是“userPostId”,这可能会导致混淆。您还可以使用@connection 上的“keyField”和“sortField”参数显式设置关键字段。以上是关于如何使用 AppSync GraphQL 转换为双向一对多 @connection 执行字段级别 @auth?的主要内容,如果未能解决你的问题,请参考以下文章
使用 GraphQL 转换在 AWS AppSync 中生成带有参数的订阅
通过 AWS AppSync GraphQL API 使用多种授权类型
如何使用 AWS appsync (GraphQL) 禁用自省查询?
如何使用 amplify 将 GraphQL 更改从 Appsync 同步到 Android?