Handling Authorisation With Apollo

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.

Front-End
TypeScript: type aliases to check type equality

This post is to analyse how the type equality check by using type aliases proposed by Matt Pocock in his twitter post. These type aliases allow us to elegantly express type equality checks in unit tests. All we need to do is to pass the output and expected types in …

Front-End
Fixing it.only type error in Jest

If you are getting a type error with it.only in Jest, it could be due to incorrect TypeScript typings or incompatible versions of Jest and TypeScript. To resolve this issue, you can try the following steps: Make sure you have the latest versions of Jest and its TypeScript typings installed …

Front-End
yup conditional validation example

Here’s an example of a Yup validation logic where the first input field is optional but, if filled, it must contain only alphabetic characters, and the second input field is required: import * as Yup from “yup”; const validationSchema = Yup.object().shape({ firstField: Yup.string().matches(/^[A-Za-z]*$/, { message: “First field must contain only …