# Context and Authorisation — GraphQL

Source: https://www.skillbyai.com/en/graphql/r-context

> Who is asking, and may they see this field?

## Authenticate once, authorise everywhere

Authenticate the request once (from a session cookie or bearer token) when building the **context**, and pass the user, data loaders and services to all resolvers. **Authorise** in the business layer or per field: because clients can reach any object through many paths in the graph, checking only at root fields is not enough. Schema directives (such as an `@auth` directive) or middleware can apply rules declaratively, but the checks must run for every field that exposes protected data.

## Field-level authorisation

Resolver sketch.

```javascript
const resolvers = {
  User: {
    // anyone who can see a user sees the name
    name: (user) => user.name,
    // only the user themself or an admin sees the email
    email: (user, _args, { viewer }) => {
      if (!viewer) throw new GraphQLError("Not authenticated", { extensions: { code: "UNAUTHENTICATED" } });
      if (viewer.id !== user.id && !viewer.isAdmin) return null;
      return user.email;
    },
  },
};
```

## Authorise the object, not the path

An order reachable via me.orders and via product.recentOrders must be protected in both places; enforce it where the order is loaded.

**Quiz:** Why is authorising only root fields insufficient in GraphQL?

- [ ] GraphQL has no authentication
- [ ] Root fields cannot have resolvers
- [ ] Context is not available in nested fields
- [x] The same data can be reached through many nested paths

*Answer:* The same data can be reached through many nested paths. Protect data where it is resolved.
