如何使用 AppSync GraphQL Transform 为双向一对多@connection 执行字段级@auth?

How to do field level @auth for bi-directional one-to-many @connection with AppSync GraphQL Transform?

我想弄清楚如何在字段级别保护一对多 @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 还很陌生,所以我想我一定没有得到什么,但这是如此常见的用例场景,我真的很惊讶没有更多关于它的文档。

非常感谢您的帮助。

恶意用户是否应该能够更新 Post 标题?我知道这不是您问题的确切答案,因为您关注的是关系领域,但是通过尝试了解如何自己做这些事情,我读了一些关于引入某种形式的 'everyone' 组,以便您可以为非所有者的用户定义身份验证。然后您可以对整个 Post 模型进行身份验证,这样只有所有者才能更新任何字段;

type Post 
  @model 
  @auth(rules: [
    { allow: owner, ownerField: "userPostId" },
    { allow: groups, groups: ["everyone"], operations: [read] }
  ]) {
  title: String!
  user: User!
    @connection(name: "UserPosts")
}

我对放大非常陌生(我目前正在评估是否将它用于我正在开始的项目),所以我在这里可能完全错了。如果你真的想要一个 semi-open 模型,其中只有参考字段有授权,我不知道该怎么做 :(

为了保护 Mutation.createPost 突变,以便只有通过 postUserId 指定的 Post 的所有者可以访问它,您将 @auth 指令添加到 Post 对象定义:

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