How to Protect GraphQL Mutation with Authentication
To protect a
GraphQL mutation with authentication, check the user's identity in the resolver before performing any data changes. Use the context object to access authentication info and reject unauthorized requests by throwing an error.Syntax
In GraphQL, mutations are protected by adding authentication checks inside the resolver function. The context parameter usually carries user info from the request. You verify the user and then allow or deny the mutation.
parent: The result from the previous resolver (usually unused here).args: The input arguments for the mutation.context: Contains authentication data like the logged-in user.info: Metadata about the execution state.
javascript
const resolvers = { Mutation: { updateProfile: (parent, args, context, info) => { if (!context.user) { throw new Error('Authentication required'); } // Proceed with mutation logic return updateUserProfile(args.input); } } };
Example
This example shows a simple GraphQL mutation resolver that updates a user's profile only if the user is authenticated. The context.user holds the logged-in user info. If no user is found, it throws an error to block the mutation.
javascript
const { ApolloServer, gql } = require('apollo-server'); const typeDefs = gql` type User { id: ID! name: String! } input ProfileInput { name: String! } type Mutation { updateProfile(input: ProfileInput!): User } type Query { me: User } `; let currentUser = { id: '1', name: 'Alice' }; const resolvers = { Mutation: { updateProfile: (parent, { input }, context) => { if (!context.user) { throw new Error('Authentication required'); } // Simulate updating user profile currentUser.name = input.name; return currentUser; } }, Query: { me: (parent, args, context) => context.user } }; const server = new ApolloServer({ typeDefs, resolvers, context: () => ({ user: currentUser }) // Simulate logged-in user }); server.listen().then(({ url }) => { console.log(`Server ready at ${url}`); });
Output
Server ready at http://localhost:4000/
Common Pitfalls
Common mistakes when protecting mutations include:
- Not checking authentication inside the resolver, which allows unauthorized access.
- Assuming authentication is handled elsewhere and skipping checks in mutations.
- Not throwing errors when the user is missing, causing silent failures or unexpected behavior.
- Exposing sensitive mutation logic without verifying user roles or permissions.
Always validate context.user and handle errors explicitly.
javascript
const resolvers = { Mutation: { // Wrong: No authentication check deletePost: (parent, args, context) => { // Deletes post without verifying user return deletePostById(args.id); }, // Right: Check authentication deletePostSecure: (parent, args, context) => { if (!context.user) { throw new Error('Authentication required'); } return deletePostById(args.id); } } };
Quick Reference
Tips to protect GraphQL mutations with authentication:
- Use
contextto pass user info from your server middleware. - Always check
context.userin mutation resolvers. - Throw errors immediately if the user is not authenticated.
- Consider adding role or permission checks for sensitive mutations.
- Test your API with and without authentication to verify protection.
Key Takeaways
Always check user authentication inside mutation resolvers using the context object.
Throw an error to block unauthorized mutation attempts.
Pass user info securely to context from your server's authentication middleware.
Add role or permission checks for sensitive data changes.
Test mutations both with and without authentication to ensure protection.