【问题标题】:How do I implement auth directive for mutations with Apollo?如何使用 Apollo 实现突变的 auth 指令?
【发布时间】:2019-05-28 23:53:38
【问题描述】:

我正在尝试为我正在处理的项目设置 Apollo 后端,我正在尝试实现架构指令。但是,我无法将我的模式指令添加到突变中。所以我的主要问题是:如何为突变实现 auth 指令?

我已将@auth(requires: ADMIN) 添加到我的用户查询末尾,它工作正常。然后,Apollo 将需要一个具有管理员访问权限的不记名令牌来执行用户查询。

extend type Query {
    user(id: ID!): User
    users: [User!]! @auth(requires: ADMIN)
}

当我尝试以相同的方式对 editMyUser 突变执行此操作时,似乎对所有突变都强制执行了 auth 指令,而不仅仅是我想要的那个。当我将 @auth 部分添加到 editMyUser 突变时,即使 signUp 突变也会给出“未授权”错误。尽管它们之间没有任何关系。

调用时应该传递给auth指令的角色字段是空的。

extend type Mutation {
    signUp(
        username: String!
        firstName: String
        lastName: String
        password: String!
        isAdmin: Boolean
        isActive: Boolean): User!
    login(
        username: String!
        password: String!): User!
    editMyUser(
        id: ID!
        firstName: String
        lastName: String
        password: String): User! @auth(requires: USER)
    adminEditUser(
        id: ID!
        firstName: String
        lastName: String
        password: String
        isActive: Boolean
        isAdmin: Boolean
        isBanned: Boolean): User!
}

这就是我实现架构指令的方式

export default gql`
directive @auth(requires: Role = ADMIN) on OBJECT | FIELD_DEFINITION

enum Role {
    ADMIN
    USER
}

https://github.com/jwhenshaw/graphql-directives-auth 这是我在代码中实现的 Auth 指令以供参考。

总而言之,当我为突变实施 auth 指令时,它们会为所有突变实施,而不仅仅是一个突变,而且它甚至无法正常工作,因为角色没有传递给指令。

我很想在这方面得到一些帮助。谢谢!

【问题讨论】:

    标签: javascript authentication graphql apollo apollo-server


    【解决方案1】:

    在该存储库中,AuthDirective 类将被包装到 ensureFieldWrapped 方法中的字段的 objectType 传递。这意味着对于您将指令直接分配到Mutation 对象上的字段editMyUser 的示例,该方法将包装Mutation 的所有子代(我相信对于您的查询实际上也是如此)。

    因此,在示例 repo 中,这很好,因为我们有一个对象类型 User,并且我们将它及其字段包装起来。但是,如果您不想这样做,我们可以更改 AuthDirective 类以仅包装它所在的字段。

    我已完成此操作并推送到 repo,https://github.com/jwhenshaw/graphql-directives-auth,您可以看到现在有一​​个 FieldAuthDirective 和一个 ObjectAuthDirective。我仍然需要稍微清理一下代码,但推送了一个工作示例并留下了一些日志以帮助突出差异。如果你不想在本地运行它,你可以在这里查看它https://qzj70qn2mj.sse.codesandbox.io/

    希望这会有所帮助,如果我需要详细说明,请告诉我。

    【讨论】:

      【解决方案2】:

      这里的问题是,当包装解析器在these lines of code 中找不到任何必需的角色(对象类型和相关字段都没有)时,引用的实现会引发错误。

      逻辑是,当您将指令用于对象类型的某些字段时,您还需要为类型本身提供要求。在我看来,这个逻辑并不算太糟糕,并且正如代码注释所暗示的那样是安全的。该实现的作者可能专注于将指令用于实际数据类型,而不是查询或突变。

      让我更具体一点:你和我所做的(因为我今天试图完成与你相同的事情),当将指令用于一个或多个查询/突变时,实际上是将指令应用于架构类型 QueryMutation 的字段。因此,如果我们不希望对我们的模式的所有查询和/或突变有最低要求,代码不应该在我上面链接的那个条件下抛出错误,但它应该调用包装的解析器,就像满足要求一样(因为没有)。

      例子:

      if (!requiredRole) {
        // No auth required, just call the resolver
        return resolve.apply(this, args);
      }
      

      我希望这会有所帮助! ?

      【讨论】:

        猜你喜欢
        • 2020-10-31
        • 2020-11-24
        • 2021-03-08
        • 2022-08-20
        • 2019-12-01
        • 2020-03-21
        • 2019-11-28
        • 2014-07-27
        • 2019-12-21
        相关资源
        最近更新 更多