我有一个包含混合公共和私有查询和变异的GraphQL API。我正在寻找一种方法来检查操作是否需要用户进行身份验证以及权限检查程序,以便用户只能修改自己的数据。
我注意到解析器函数有第四个参数info
,其中包含path.key
,它返回操作的名称(记录为here)。
我的解决方案是在每个解析器中添加一个checker函数,如下所示:
// modify user details
resolve: async (parent, args, { mongo: { User }, loggedUser }, info) => {
// auth check
authChecker(info.path.key, loggedUser, args.id);
// continue resolving
},
在另一个档案中:
function authChecker(operationName, loggedUser, userId) {
if (PUBLIC_OPERATIONS.includes(operationName) {
// public operation
return true;
} else {
// private operation
if (args.id) {
// private operation that requires a permission check
...
} else {
// private operation that only requires user to be logged in
...
}
}
}
如果不满足条件,该函数将返回true或抛出错误。
我想知道这是否是一个好的解决方案,或者是否有一种方法可以用中间件以某种方式完成,这样我就不必在每个解析器中重复代码了。问题是,如果我使用中间件,我将无法访问操作名称。有什么建议吗?
答案 0 :(得分:1)
应该可以使用中间件,但是会很痛苦,因为你必须自己解析查询。我认为最干净的方法是使用模式级解析器,graphql-tools可以使用该解析器。
const {makeExecutableSchema, addSchemaLevelResolveFunction} = require('graphql-tools')
const schema = makeExecutableSchema({typeDefs, resolvers})
addSchemaLevelResolveFunction(schema, (root, args, context, info) => {
// check info to see if query is private and throw if user isn't authenticated
})
// use the schema like normal
app.use('/graphql', graphqlHTTP({schema}))
解析器不需要返回任何东西;当身份验证失败时,它只需要抛出或返回被拒绝的Promise。有关使用graphql-tools生成架构的详细信息,请查看文档here。