我正在尝试为我正在处理的项目设置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指令时,它们针对所有突变而不是仅针对一个突变而实现,并且由于角色没有传递给该指令,它甚至无法正常工作。
我很想得到一些帮助。谢谢!
答案 0 :(得分:3)
在该仓库中,AuthDirective
类将被包装在objectType
方法中的字段的ensureFieldWrapped
传递。这意味着在您的示例中,您将指令直接分配到editMyUser
对象上的字段Mutation
上,该方法将Mutation
的所有子代包装起来(我相信实际上,您的查询也应如此。
因此,在示例存储库中,这很好,因为我们有一个对象类型User
,并且包装了它及其字段。但是,如果您不希望这样做,可以更改AuthDirective
类以仅包装其所在的字段。
我已完成此操作并将其推送到仓库https://github.com/jwhenshaw/graphql-directives-auth,您可以在此处看到FieldAuthDirective
和ObjectAuthDirective
。我仍然需要稍微清理一下代码,但是推送了一个有效的示例,并留下了一些日志来帮助突出这些差异。如果您不希望在本地运行它,可以在https://qzj70qn2mj.sse.codesandbox.io/处查看。
希望这会有所帮助,让我知道是否需要详细说明。
答案 1 :(得分:1)
这里的问题是,当包装解析器未在these lines of code中找到任何必需的角色(对象类型和相关字段均未使用)时,引用的实现将引发错误。
逻辑是,当您将指令用于对象类型的某些字段时,还需要提供类型本身的要求。我认为这种逻辑还不错,正如代码注释所建议的那样是安全的。该实现的作者可能专注于将指令用于实际数据类型,而不是用于查询或变异。
让我更具体一点:当您将指令用于一个或多个查询/更改时,您和我所做的事情(因为我正在努力完成与您今天相同的事情)实际上是在模式Query
和Mutation
的字段。因此,如果我们不希望对架构的所有查询和/或更改都具有最低要求,则代码不应在我上面链接的那种情况下引发错误,而应像满足要求一样调用包装的解析程序(因为没有)。
示例:
if (!requiredRole) {
// No auth required, just call the resolver
return resolve.apply(this, args);
}
我希望这会有所帮助!