简体   繁体   中英

GraphQL resolver middleware for auth check

I have a GraphQL API with mixed public and private queries and mutation. 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 ).

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.

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 .

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. For more info about generating a schema with graphql-tools, check the docs here .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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