如何使用 Apollo 实现突变的 auth 指令?
How do I implement auth directive for mutations with Apollo?
我正在尝试为我正在处理的项目设置一个 Apollo 后端,我正在尝试在其中实现模式指令。但是,我无法将我的模式指令添加到突变中。所以我的主要问题是:如何为突变实施 auth 指令?
我已将 @auth(requires: ADMIN)
添加到我的用户查询的末尾,效果很好。然后,Apollo 将需要一个具有管理员访问权限的持有者令牌来执行用户查询。
extend type Query {
user(id: ID!): User
users: [User!]! @auth(requires: ADMIN)
}
当我尝试以相同的方式对 editMyUser 突变执行此操作时,似乎对所有突变都强制执行了 auth 指令,而不仅仅是我想要的突变。当我将 @auth 部分添加到 editMyUser 突变时,即使是 signUp 突变也会出现 "not authorized" 错误。虽然他们之间没有关系。
调用时应该传递给 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 Directive 以供参考。
总而言之,当我为突变实现 auth 指令时,它们是为所有突变实现的,而不仅仅是一个突变,它甚至无法正常工作,因为角色没有传递给指令。
我很乐意就此获得一些帮助。谢谢!
这里的问题是,当包装解析器在 these lines of code 中找不到任何必需的角色(无论是对象类型还是相关字段)时,引用的实现都会抛出错误。
逻辑是,当您对对象类型的某些字段使用指令时,您还需要为类型本身提供要求。在我看来,这种逻辑并不算太糟糕,而且正如代码注释所建议的那样,为了安全起见。该实现的作者可能专注于将指令用于实际数据类型,而不是用于查询或突变。
让我说得更具体一点:你和我所做的(因为我今天正试图完成与你相同的事情),当对一个或多个 queries/mutations 使用指令时,实际上是在应用模式类型 Query
和 Mutation
字段上的指令。因此,如果我们不希望对我们模式的所有查询 and/or 突变有最低要求,代码不应在我上面链接的那种情况下抛出错误,但它应该调用包装的解析器,就像要求是遇到了(因为有none)。
示例:
if (!requiredRole) {
// No auth required, just call the resolver
return resolve.apply(this, args);
}
希望对您有所帮助!
在该 repo 中,AuthDirective
class 将被包装的字段的 objectType
传递到 ensureFieldWrapped
方法中。这意味着对于您将指令直接分配到字段 editMyUser
的示例,在 Mutation
的对象上,该方法正在包装 Mutation
的所有子项(我相信实际上,您的查询也应该如此。
因此,在示例存储库中,这很好,因为我们有一个对象类型 User
并且我们包装了它及其字段。但是,如果您不想这样做,我们可以更改 AuthDirective
class 以仅包装它所在的字段。
我已经完成并推送到回购协议,https://github.com/jwhenshaw/graphql-directives-auth, where you can see there is now a FieldAuthDirective
and a ObjectAuthDirective
. I still need to clean the code a bit but pushed a working example and left some logs to help highlight the differences. You can view it here https://qzj70qn2mj.sse.codesandbox.io/ 如果你不喜欢 运行 它在本地。
希望这对您有所帮助,如果我需要详细说明,请告诉我。
我正在尝试为我正在处理的项目设置一个 Apollo 后端,我正在尝试在其中实现模式指令。但是,我无法将我的模式指令添加到突变中。所以我的主要问题是:如何为突变实施 auth 指令?
我已将 @auth(requires: ADMIN)
添加到我的用户查询的末尾,效果很好。然后,Apollo 将需要一个具有管理员访问权限的持有者令牌来执行用户查询。
extend type Query {
user(id: ID!): User
users: [User!]! @auth(requires: ADMIN)
}
当我尝试以相同的方式对 editMyUser 突变执行此操作时,似乎对所有突变都强制执行了 auth 指令,而不仅仅是我想要的突变。当我将 @auth 部分添加到 editMyUser 突变时,即使是 signUp 突变也会出现 "not authorized" 错误。虽然他们之间没有关系。
调用时应该传递给 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 Directive 以供参考。
总而言之,当我为突变实现 auth 指令时,它们是为所有突变实现的,而不仅仅是一个突变,它甚至无法正常工作,因为角色没有传递给指令。
我很乐意就此获得一些帮助。谢谢!
这里的问题是,当包装解析器在 these lines of code 中找不到任何必需的角色(无论是对象类型还是相关字段)时,引用的实现都会抛出错误。
逻辑是,当您对对象类型的某些字段使用指令时,您还需要为类型本身提供要求。在我看来,这种逻辑并不算太糟糕,而且正如代码注释所建议的那样,为了安全起见。该实现的作者可能专注于将指令用于实际数据类型,而不是用于查询或突变。
让我说得更具体一点:你和我所做的(因为我今天正试图完成与你相同的事情),当对一个或多个 queries/mutations 使用指令时,实际上是在应用模式类型 Query
和 Mutation
字段上的指令。因此,如果我们不希望对我们模式的所有查询 and/or 突变有最低要求,代码不应在我上面链接的那种情况下抛出错误,但它应该调用包装的解析器,就像要求是遇到了(因为有none)。
示例:
if (!requiredRole) {
// No auth required, just call the resolver
return resolve.apply(this, args);
}
希望对您有所帮助!
在该 repo 中,AuthDirective
class 将被包装的字段的 objectType
传递到 ensureFieldWrapped
方法中。这意味着对于您将指令直接分配到字段 editMyUser
的示例,在 Mutation
的对象上,该方法正在包装 Mutation
的所有子项(我相信实际上,您的查询也应该如此。
因此,在示例存储库中,这很好,因为我们有一个对象类型 User
并且我们包装了它及其字段。但是,如果您不想这样做,我们可以更改 AuthDirective
class 以仅包装它所在的字段。
我已经完成并推送到回购协议,https://github.com/jwhenshaw/graphql-directives-auth, where you can see there is now a FieldAuthDirective
and a ObjectAuthDirective
. I still need to clean the code a bit but pushed a working example and left some logs to help highlight the differences. You can view it here https://qzj70qn2mj.sse.codesandbox.io/ 如果你不喜欢 运行 它在本地。
希望这对您有所帮助,如果我需要详细说明,请告诉我。