Handling Authorisation With Apollo
- By : Mydatahack
- Category : Node.js, Web Technologies
- Tags: Apollo, GraphQL, Node.js
There are many ways to handle authorisation with Apollo. Authorisation is the process to determine if the authenticated user has access rights for the particular resources while authentication is to confirm the user’s identity.
In short, my recommendation is (5), by using graphql-shield. You can also check the code example for handling authorisation with graphql-shield here.
(1) Implementing Authorisation in a Resolver
This is the simplest way, but not very scalable. As an example, we can pass a user object in the context. By using the information about the user’s role, we can write an if-else condition.
movie: (parent, arg, { user, dataSources }, info) => { if (user && user.role === 'ADMIN') { return dataSources.getMovies(); } }
(2) Implementing Authorisation in a Model
Create a model and control data access. The below example is to check the user role and can query any user if the role is set to ADMIN and can only query their own data if the role is set to USER. It’s cool, but convoluted in my opinion.
import { getUserById } from '../datasources/user'; const userModel = ({ user }) => { return ( getById: (id) => { if (user) { if (user.role === 'ADMIN') { return getUserById(id); } if (user.role === 'USER') { return getUserById(user.id); } } } ) }
Then, we can pass this in the context’s return value where you do new ApolloServer(). This can be used in the repository method.
return ( user, otherThings, models: { User: generateUserModel({ user }) } )
(3) Using Schema Directive
We can create a custom schema directive as in the documentation here.
(4) Wrap a resolver function with graphql-auth
We can use the node module, graphql-auth, to wrap the resolver function as below. It’s pretty nice.
import withAuth from 'graphql-auth'; const resolvers = { Query: { users: withAuth(['users:view'], (root, args, context) => { ... }), ... } }
(5) Use graphql-shield
This is the recommended way to handle authorisation with Apollo. graphql-shield can completely abstract the authentication from the resolver. It is the cleanest and easiest way to handle authorisation. Because the permission rules are abstracted, it is easy to manage when the app starts scaling up. It works well with Apollo Federation, too.
See my code example of using graphql-shield to handle authorisation here.