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?