【问题标题】:How to do field level @auth for bi-directional one-to-many @connection with AppSync GraphQL Transform?如何使用 AppSync GraphQL 转换为双向一对多 @connection 执行字段级别 @auth?
【发布时间】: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 还很陌生,所以我想我一定没有得到任何东西,但这是如此常见的用例场景,我真的很惊讶没有更多关于它的文档。

我们将不胜感激。

【问题讨论】:

    标签: graphql aws-amplify aws-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”参数显式设置关键字段。
      猜你喜欢
      • 2020-07-14
      • 2020-04-25
      • 2019-12-29
      • 2020-04-10
      • 2020-09-22
      • 2022-11-13
      • 2019-09-06
      • 2020-07-12
      • 1970-01-01
      相关资源
      最近更新 更多