如何使用 Apollo 为突变实现 auth 指令?

Jør*_*Vik 5 javascript authentication apollo graphql apollo-server

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

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

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

当我尝试以相同的方式对 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!
}
Run Code Online (Sandbox Code Playgroud)

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

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

enum Role {
    ADMIN
    USER
}
Run Code Online (Sandbox Code Playgroud)

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

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

我很想得到一些帮助。谢谢!

小智 5

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

所以,在示例 repo 中,这很好,因为我们有一个 Object 类型User,我们包装它和它的字段。但是,如果您不想这样做,我们可以更改AuthDirective该类以仅包装它所在的字段。

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

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