简体   繁体   English

用于授权检查的GraphQL解析器中间件

[英]GraphQL resolver middleware for auth check

I have a GraphQL API with mixed public and private queries and mutation. 我有一个GraphQL API,其中混合了公共和私有查询以及变异。 I'm looking for a way to check whether an operation requires the user to be authenticated and also a permission checker, so that the user can only modify his own data. 我正在寻找一种检查操作是否需要对用户进行身份验证以及权限检查器的方法,以便用户只能修改自己的数据。

I noticed that the resolver function has a fourth argument, info that includes path.key which returns the name of the operation (documented here ). 我注意到,解析器函数有第四个参数, info包含path.key ,该path.key返回操作的名称( 在此处记录 )。

My solution was to add a checker function inside every resolver, like so: 我的解决方案是在每个解析器中添加一个检查器函数,如下所示:

// modify user details
resolve: async (parent, args, { mongo: { User }, loggedUser }, info) => {
    // auth check
    authChecker(info.path.key, loggedUser, args.id);

  // continue resolving
},

And in another file: 并在另一个文件中:

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
      ...
    }
  }
}

The function either returns true or throws an error if conditions are not met. 如果不满足条件,该函数将返回true或引发错误。

I was wondering if this was an ok solution or if there was a way that this could be done with a middleware somehow so that I wouldn't have to repeat the code in every resolver. 我想知道这是否是一个好的解决方案,或者是否可以通过某种方式使用中间件来做到这一点,这样我就不必在每个解析器中都重复代码了。 The problem is that I wouldn't have access to the operation name if I'd use a middleware. 问题是,如果我使用中间件,我将无权访问操作名称。 Any suggestions? 有什么建议么?

Utilizing middleware should be possible, but would be painful because you would have to parse the query yourself. 使用中间件应该是可能的,但是会很痛苦,因为您必须自己解析查询。 I think the cleanest way is to utilize a schema-level resolver, which is available with graphql-tools . 我认为最干净的方法是利用schemaql-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}))

The resolver doesn't need to return anything; 解析器不需要返回任何东西; it just needs to throw or return a rejected Promise when authentication fails. 它只需要在身份验证失败时抛出或返回被拒绝的Promise。 For more info about generating a schema with graphql-tools, check the docs here . 有关使用graphql-tools生成模式的更多信息,请在此处查看文档。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM